package jnpf.engine.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jnpf.base.ActionResult;
import jnpf.base.Pagination;
import jnpf.base.UserInfo;
import jnpf.config.ConfigValueUtil;
import jnpf.constant.PermissionConst;
import jnpf.engine.assembly.GlobalExPropertyDTO;
import jnpf.engine.custom.behavior.impl.CustomCallActivityActivityBehavior;
import jnpf.engine.custom.behavior.impl.CustomManualTaskActivityBehavior;
import jnpf.engine.custom.cmd.commons.ExpressionCmd;
import jnpf.engine.custom.cmd.commons.GetExecutionEntityManagerCmd;
import jnpf.engine.custom.cmd.commons.GetSecondExecutionIdCmd;
import jnpf.engine.custom.cmd.commons.RemoveProcCmd;
import jnpf.engine.custom.cmd.tasks.ActiveTaskCmd;
import jnpf.engine.custom.cmd.tasks.FindMemoryTaskCmd;
import jnpf.engine.custom.cmd.tasks.SuspendTaskCmd;
import jnpf.engine.custom.constants.BasicActivitiConstants;
import jnpf.engine.custom.constants.RootExecutionVariableConstants;
import jnpf.engine.custom.exception.PointAssigneeException;
import jnpf.engine.entity.*;
import jnpf.engine.enums.*;
import jnpf.engine.model.FlowTaskDTO;
import jnpf.engine.model.FlowTaskNodeDTO;
import jnpf.engine.model.FlowTaskOperatorRecordDTO;
import jnpf.engine.model.flowbefore.*;
import jnpf.engine.model.flowcandidate.FlowCandidateListModel;
import jnpf.engine.model.flowcandidate.FlowCandidateUserModel;
import jnpf.engine.model.flowcandidate.FlowCandidateVO;
import jnpf.engine.model.flowcandidate.FlowRejectVO;
import jnpf.engine.model.flowengine.AddMultiFlowModel;
import jnpf.engine.model.flowengine.FlowModel;
import jnpf.engine.model.flowengine.FlowOperatordModel;
import jnpf.engine.model.flowengine.shuntjson.childnode.Properties;
import jnpf.engine.model.flowengine.shuntjson.childnode.*;
import jnpf.engine.model.flowengine.shuntjson.nodejson.ChildNodeList;
import jnpf.engine.model.flowengine.shuntjson.nodejson.ConditionList;
import jnpf.engine.model.flowmessage.FlowMsgModel;
import jnpf.engine.model.flowmessage.FlowParameterModel;
import jnpf.engine.model.flowtask.FlowConditionModel;
import jnpf.engine.model.flowtask.TaskNodeModel;
import jnpf.engine.model.flowtask.WorkTimeoutJobModel;
import jnpf.engine.model.flowtasknode.TaskNodeListModel;
import jnpf.engine.service.*;
import jnpf.engine.util.*;
import jnpf.entity.FlowFormEntity;
import jnpf.exception.WorkFlowException;
import jnpf.job.WorkTimeoutJobUtil;
import jnpf.model.flow.FlowFormDataModel;
import jnpf.model.form.FlowFormVo;
import jnpf.permission.entity.*;
import jnpf.permission.service.UserService;
import jnpf.util.*;
import jnpf.util.visiual.JnpfKeyConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.NoneEndEventActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.ReceiveTaskActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.script.ScriptEngine;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static jnpf.engine.custom.constants.BasicActivitiConstants.*;
import static jnpf.engine.custom.constants.GlobalProcessVariableConstants.*;
import static jnpf.engine.custom.constants.RedisConstants.LOCK_STR;
import static jnpf.engine.custom.constants.RootExecutionVariableConstants.MULTI_INSTANCE_NUM_AUDIT;
import static jnpf.engine.custom.constants.TaskVariableConstants.COUNTER_SIGN_COMPLETE;
import static jnpf.engine.util.BpmnModelUtils.*;
import static jnpf.engine.util.EvalUtils.*;

/**
 * 流程引擎
 *
 * @author JNPF开发平台组
 * @version V3.2.0
 * @copyright 引迈信息技术有限公司
 * @date 2021年4月27日 上午9:18
 */
@Service
@Slf4j
@SuppressWarnings("all")
public class FlowTaskNewServiceImpl implements FlowTaskNewService {

    @Autowired
    private ServiceAllUtil serviceUtil;
    @Autowired
    private FlowUserService flowUserService;
    @Autowired
    private FlowCandidatesService flowCandidatesService;
    @Autowired
    private FlowTaskNodeService flowTaskNodeService;
    @Autowired
    private FlowTaskOperatorService flowTaskOperatorService;
    @Autowired
    private FlowTaskOperatorRecordService flowTaskOperatorRecordService;
    @Autowired
    private FlowTaskCirculateService flowTaskCirculateService;
    @Autowired
    private FlowTaskShareService flowTaskShareService;
    @Autowired
    private FlowRejectDataService flowRejectDataService;
    @Autowired
    private FlowTaskService flowTaskService;
    @Autowired
    private FlowTaskUtil flowTaskUtil;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private FlowOperatorUserService flowOperatorUserService;
    @Autowired
    private FlowMsgUtil flowMsgUtil;
    @Autowired
    private FlowEventLogService flowEventLogService;
    @Autowired
    private FlowDelegateService flowDelegateService;
    @Autowired
    @Lazy
    private WorkTimeoutJobUtil workTimeoutJobUtil;
    @Autowired
    private UserProvider userProvider;
    @Resource
    private TaskService taskService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private HistoryService historyService;
    @Resource
    private ManagementService managementService;
    @Resource
    private ActivitiUtils activitiUtils;
    @Resource
    private ConfigValueUtil configValueUtil;
    @Resource
    private UserService userService;
    @Autowired
    private FlowTemplateJsonService flowTemplateJsonService;
    @Resource
    private ScriptEngine scriptEngine;
    @Resource
    private JdbcTemplate jdbcTemplate;
    @Resource
    private FlowAddNodeTemplateEntityService flowAddNodeTemplateEntityService;
    @Resource
    private ProcessEngine processEngine;
    @Resource
    private FlowRunAddNodeTemplateEntityService flowRunAddNodeTemplateEntityService;

    @Override
    public FlowTaskEntity saveIsAdmin(FlowModel flowModel) throws WorkFlowException {
        FlowTaskEntity entity = save(flowModel);
        return entity;
    }

    @Override
    @DSTransactional
    public FlowTaskEntity save(FlowModel flowModel) throws WorkFlowException {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(flowModel.getProcessId()).singleResult();
        //第一次
        if(processInstance==null){
            Map<String,Object> variablesMap = new HashMap<>();
            if(StringUtils.isNotBlank(flowModel.getDelegateUser())){
                variablesMap.put(DELEGATE_USER_ID,flowModel.getDelegateUser());
            }
            String flowId = flowModel.getFlowId();
            UserInfo userInfo = flowModel.getUserInfo();
            flowModel.setStatus(StringUtil.isNotEmpty(flowModel.getStatus()) ? flowModel.getStatus() : FlowStatusEnum.save.getMessage());
            flowModel.setUserId(StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId());

            //流程引擎
            FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJsonNoLongText(flowId);
            FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
            FlowTemplateEntity template = templateAllModel.getTemplate();
            //判断
            if(StringUtils.isBlank(templateJson.getProcessDefinitionId())){
                throw new WorkFlowException("该流程属于内置数据,还没有发布!请去流程引擎页面重新发布一下!");
            }
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(templateJson.getProcessDefinitionId()).singleResult();
            if(processDefinition.isSuspended()){
                throw new WorkFlowException("流程已经挂起,请先激活!");
            }
            String fullName = templateJson.getFullName();
            //流程实例
            String flowTitle = StringUtil.isNotEmpty(flowModel.getFlowTitle()) ? flowModel.getFlowTitle() : userInfo.getUserName() + "的" + fullName;
            Properties properties = getFirstNodeProperty(templateJson.getProcessDefinitionId());
            Map<String, Object> data = flowModel.getFormData() != null ? flowModel.getFormData() : new HashMap<>();
            data.put("@flowFullName", fullName);
            data.put("@flowFullCode", template.getEnCode());
            data.put("@launchUserName", userInfo.getUserName());
            data.put("@launchTime", DateUtil.daFormat(new Date()));
            if (!FlowNature.TitleType.equals(properties.getTitleType())) {
                flowTitle = FlowJsonUtil.field(properties.getTitleContent(), data, "1");
            }
            flowModel.setFlowTitle(flowTitle);

            variablesMap.put(BUSINESS_TITLE,flowTitle);
            variablesMap.put(PROCESS_CATEGORY,template.getCategory());
            if(StringUtils.isNotBlank(flowModel.getBillNo())){
                variablesMap.put(BILL_CODE,flowModel.getBillNo());
            }
            variablesMap.put(FLOW_URGENT,flowModel.getFlowUrgent());
            variablesMap.put(PROCESS_STATUS,FlowTaskStatusEnum.Draft.getCode());
            variablesMap.put(APPLY_USER_ID,flowModel.getTrueAssignee());
            variablesMap.put(CURRENT_CREATE_TIME,new Date());
            variablesMap.put(BUSINESS_KEY,flowModel.getProcessId());
            variablesMap.put(FLOW_ENGINE_ID,templateJson.getTemplateId());
            variablesMap.put(FLOW_TEMPLATE_JSON_ID,templateJson.getId());
            variablesMap.put(BATCH_FLAG,templateJson.getBatch());

            Authentication.setAuthenticatedUserId(flowModel.getTrueAssignee());
            try{
                runtimeService.createProcessInstanceBuilder()
                        .processDefinitionId(templateJson.getProcessDefinitionId())
                        .businessKey(flowModel.getProcessId())
                        .variables(variablesMap)
                        .name(flowTitle)
                        .tenantId(userInfo.getTenantId())
                        .start();


            }catch (Exception e){
                e.printStackTrace();
                throw new WorkFlowException("启动流程失败");
            }
            finally {
                //此线程不安全 用完就需要在finally中释放
                Authentication.setAuthenticatedUserId(null);
            }
        }
        //最后一次
        else{
            boolean suspended = processInstance.isSuspended();
            if(suspended){
                throw new WorkFlowException("该流程已被挂起,请重试");
            }
            //也需要更新表单数据
            runtimeService.setVariable(processInstance.getId(),FLOW_URGENT,flowModel.getFlowUrgent());
        }
        return null;

//        String flowId = flowModel.getFlowId();
//        UserInfo userInfo = flowModel.getUserInfo();
//        flowModel.setStatus(StringUtil.isNotEmpty(flowModel.getStatus()) ? flowModel.getStatus() : FlowStatusEnum.save.getMessage());
//        flowModel.setUserId(StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId());
//        //流程引擎
//        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowId);
//        FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
//        FlowTemplateEntity template = templateAllModel.getTemplate();
//        FlowTaskEntity infoSubmit = flowTaskService.getInfoSubmit(flowModel.getProcessId(),
//                FlowTaskEntity::getStatus, FlowTaskEntity::getCreatorUserId, FlowTaskEntity::getIsAsync,
//                FlowTaskEntity::getSystemId, FlowTaskEntity::getFullName, FlowTaskEntity::getParentId,
//                FlowTaskEntity::getId, FlowTaskEntity::getRejectId
//        );
//        boolean isTask = infoSubmit != null;
//        String fullName = templateJson.getFullName();
//        //流程实例
//        String flowTitle = StringUtil.isNotEmpty(flowModel.getFlowTitle()) ? flowModel.getFlowTitle() : userInfo.getUserName() + "的" + fullName;
//        FlowTaskEntity flowTaskEntity = new FlowTaskEntity();
//        flowTaskEntity.setParentId(flowModel.getParentId());
//        flowTaskEntity.setIsAsync(FlowNature.ChildSync);
//        flowTaskEntity.setFullName(flowTitle);
//        flowTaskEntity.setStatus(FlowTaskStatusEnum.Draft.getCode());
//        flowTaskEntity.setSystemId(flowModel.getSystemId());
//        FlowTaskEntity taskEntity = isTask ? infoSubmit : flowTaskEntity;
//        if (isTask) {
//            //判断流程是否处于挂起状态
//            flowTaskUtil.isSuspend(taskEntity);
//            flowModel.setStatus(FlowStatusEnum.save.getMessage().equals(flowModel.getStatus()) ? FlowStatusEnum.none.getMessage() : flowModel.getStatus());
//            flowModel.setUserId(taskEntity.getCreatorUserId());
//            flowModel.setIsAsync(FlowNature.ChildAsync.equals(taskEntity.getIsAsync()));
//            flowModel.setSystemId(taskEntity.getSystemId());
//            flowTitle = taskEntity.getFullName();
//        }
//        if (!FlowNature.ParentId.equals(taskEntity.getParentId())) {
//            flowModel.setParentId(taskEntity.getParentId());
//            flowTitle = taskEntity.getFullName();
//        }
//        ChildNode childNodeAll = JsonUtil.getJsonToBean(templateJson.getFlowTemplateJson(), ChildNode.class);
//        Properties properties = childNodeAll.getProperties();
//        Map<String, Object> data = flowModel.getFormData() != null ? flowModel.getFormData() : new HashMap<>();
//        data.put("@flowFullName", fullName);
//        data.put("@flowFullCode", template.getEnCode());
//        data.put("@launchUserName", userInfo.getUserName());
//        data.put("@launchTime", DateUtil.daFormat(new Date()));
//        if (!FlowNature.TitleType.equals(properties.getTitleType())) {
//            flowTitle = FlowJsonUtil.field(properties.getTitleContent(), data, "1");
//            flowTitle += !FlowNature.ParentId.equals(flowModel.getParentId()) ? "(子流程)" : "";
//        }
//        flowModel.setFlowTitle(flowTitle);
//        flowTaskUtil.task(taskEntity, templateAllModel, flowModel);
//        //更新流程任务
//        if (isTask) {
//            flowTaskService.update(taskEntity);
//        } else {
//            flowTaskService.create(taskEntity);
//        }
//        return taskEntity;
    }

    @Override
    public void submit(FlowModel flowModel) throws WorkFlowException {

    }

    @Override
    @DSTransactional
    public void submitAll(FlowModel flowModel) throws WorkFlowException {
        try {
            //进入此方法 只可能有2种情况, 先暂存,再提交,  和直接提交
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(flowModel.getProcessId()).singleResult();
            //第一次
            if (processInstance == null) {
                Map<String, Object> variablesMap = new HashMap<>();
                if (StringUtils.isNotBlank(flowModel.getDelegateUser())) {
                    variablesMap.put(DELEGATE_USER_ID, flowModel.getDelegateUser());
                }
                String flowId = flowModel.getFlowId();
                UserInfo userInfo = flowModel.getUserInfo();
                flowModel.setStatus(StringUtil.isNotEmpty(flowModel.getStatus()) ? flowModel.getStatus() : FlowStatusEnum.save.getMessage());
                flowModel.setUserId(StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId());
                //流程引擎
                FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJsonNoLongText(flowId);
                FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
                FlowTemplateEntity template = templateAllModel.getTemplate();
                String fullName = templateJson.getFullName();
                //判断
                if (StringUtils.isBlank(templateJson.getProcessDefinitionId())) {
                    throw new WorkFlowException("该流程属于内置数据,还没有发布!请去流程引擎页面重新发布一下!");
                }
                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(templateJson.getProcessDefinitionId()).singleResult();
                if (processDefinition.isSuspended()) {
                    throw new WorkFlowException("流程已经挂起,请先激活!");
                }


                //流程实例
                String flowTitle = StringUtil.isNotEmpty(flowModel.getFlowTitle()) ? flowModel.getFlowTitle() : userInfo.getUserName() + "的" + fullName;
                Properties properties = getFirstNodeProperty(templateJson.getProcessDefinitionId());
                Map<String, Object> data = flowModel.getFormData() != null ? flowModel.getFormData() : new HashMap<>();
                data.put("@flowFullName", fullName);
                data.put("@flowFullCode", template.getEnCode());
                data.put("@launchUserName", userInfo.getUserName());
                data.put("@launchTime", DateUtil.daFormat(new Date()));
                if (!FlowNature.TitleType.equals(properties.getTitleType())) {
                    flowTitle = FlowJsonUtil.field(properties.getTitleContent(), data, "1");
                }
                flowModel.setFlowTitle(flowTitle);

                variablesMap.put(BUSINESS_TITLE, flowTitle);
                variablesMap.put(PROCESS_CATEGORY, template.getCategory());
                if (StringUtils.isNotBlank(flowModel.getBillNo())) {
                    variablesMap.put(BILL_CODE, flowModel.getBillNo());
                }
                variablesMap.put(FLOW_URGENT, flowModel.getFlowUrgent());
                variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());
                variablesMap.put(APPLY_USER_ID, flowModel.getTrueAssignee());
                variablesMap.put(CURRENT_CREATE_TIME, new Date());
                variablesMap.put(BUSINESS_KEY, flowModel.getProcessId());
                variablesMap.put(FLOW_ENGINE_ID,templateJson.getTemplateId());
                variablesMap.put(FLOW_TEMPLATE_JSON_ID,templateJson.getId());
                variablesMap.put(BATCH_FLAG,templateJson.getBatch());
                Map<String, List<String>> candidateList = flowModel.getCandidateList();
                if(CollUtil.isNotEmpty(candidateList)){
                    Set<String> nodeKeys = candidateList.keySet();
                    for (String nodeKey : nodeKeys) {
                        List<String> userList = candidateList.get(nodeKey);
                        variablesMap.put(nodeKey+"PointAssigneeList",userList);
                    }
                }
                Map<String, List<String>> errorRuleUserList = flowModel.getErrorRuleUserList();
                if(CollUtil.isNotEmpty(errorRuleUserList)){
                    Set<String> nodeKeys = errorRuleUserList.keySet();
                    for (String nodeKey : nodeKeys) {
                        List<String> userList = errorRuleUserList.get(nodeKey);
                        variablesMap.put(nodeKey+"PointAssigneeList",userList);
                    }
                }


                try {
                    Authentication.setAuthenticatedUserId(flowModel.getTrueAssignee());
                    processInstance = runtimeService.createProcessInstanceBuilder()
                            .processDefinitionId(templateJson.getProcessDefinitionId())
                            .businessKey(flowModel.getProcessId())
                            .variables(variablesMap)
                            .name(flowTitle)
                            .tenantId(userInfo.getTenantId())
                            .start();


                    List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();

                    org.flowable.task.api.Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
                    flowTaskUtil.circulateInitList(circulateList,flowModel,task.getId(),variablesMap,false);
                    if(CollUtil.isNotEmpty(circulateList)){
                        flowTaskCirculateService.create(circulateList);
                        MsgConfig copyMsgConfig = properties.getCopyMsgConfig();
                        Integer on = copyMsgConfig.getOn();
                        Boolean messageFlag=false;
                        if(on!=0){
                            messageFlag=true;
                        }
                        if(messageFlag){
                            FlowMsgModel flowMsgModel = new FlowMsgModel();
                            if(CollUtil.isNotEmpty(circulateList)){
                                flowMsgModel.setCirculateList(circulateList);
                                flowMsgModel.setCopy(Boolean.TRUE);
                            }
                            flowMsgModel.setWait(Boolean.FALSE);
                            flowMsgModel.setStartNodeProperties(properties);
                            flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
                            List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
                            LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                            lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId());
                            FlowTaskOperatorEntity operatorServiceOne = flowTaskOperatorService.getOne(lambdaQueryWrapper);
                            operatorEntityList.add(operatorServiceOne);
                            flowMsgModel.setOperatorList(operatorEntityList);
                            flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
                            FlowTaskDTO flowTask = new FlowTaskDTO();
                            flowTask.setCreatorUserId(flowModel.getTrueAssignee());
                            flowTask.setStatus( FlowTaskStatusEnum.Handle.getCode());
                            flowTask.setFullName(flowTitle);
                            flowMsgModel.setTaskEntity(flowTask);

                            FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
                            flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
                            flowTaskNodeDTO.setTaskNodeId(task.getId());
                            flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);

                            flowModel.setUserInfo(UserProvider.getUser());
                            flowMsgModel.setFlowModel(flowModel);
//                    flowMsgModel.setUserInfo(UserProvider.getUser());
                            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
                            flowMsgModel.setTaskId(task.getProcessInstanceId());
                            flowMsgModel.setTaskNodeId(task.getId());
                            flowMsgUtil.message(flowMsgModel);
                        }
                    }


//                    LambdaQueryWrapper<FlowTaskOperatorEntity> flowTaskOperatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                    flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId, task.getId());
//                    flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,flowModel.getTrueAssignee());
//                    FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(flowTaskOperatorEntityLambdaQueryWrapper);
                    //开始事件
//                    FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
//                    FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder()
//                            .status(FlowRecordEnum.submit.getCode()).flowModel(flowModel)
//                            .userId(flowModel.getTrueAssignee()).operator(operator).build();
//                    flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
//                    flowTaskOperatorRecordService.create(operatorRecord);

                    LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper= new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId, task.getId());
                    lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getHandleId,flowModel.getTrueAssignee());
                    List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(lambdaQueryWrapper);
                    for (FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity : list) {
                        flowTaskOperatorRecordEntity.setHandleTime(new Date());
                    }

                    flowTaskOperatorRecordService.updateBatchById(list);
                    Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
                    Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
                    FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
                    flowTaskOperatorRecordDTO.setAssignee(flowModel.getTrueAssignee());
                    flowTaskOperatorRecordDTO.setProcessInstanceId(task.getProcessInstanceId());
                    flowTaskOperatorRecordDTO.setTaskId(task.getId());
                    Map<String, Object> formData = flowModel.getFormData();
                    formData.put("processDefinitionId",processDefinition.getId());
                    formData.put("processDefinitionName",flowTitle);
                    formData.put(BUSINESS_TITLE,flowTitle);
                    formData.put(APPLY_USER_ID,flowModel.getTrueAssignee());
                    formData.put(BUSINESS_KEY,flowModel.getProcessId());
                    //开始事件
                    flowMsgUtil.event(1, firstNodeProperty, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,task.getTaskDefinitionKey());

                    //
                    List<String> branchList = flowModel.getBranchList();
                    if(CollUtil.isNotEmpty(branchList)){
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(processInstance.getId())
                                .moveSingleActivityIdToActivityIds(task.getTaskDefinitionKey(),branchList)
                                .changeState();

                    }
                    else{
                        taskService.complete(task.getId());
                    }



                }
                catch (PointAssigneeException e){
                    String message = e.getMessage();
//                    Map map = JSONObject.parseObject(message, new TypeReference<Map>() {
//                    });
//                    List<Map> list = new ArrayList<>();
//                    list.add(map);
                    throw new PointAssigneeException(message);
                }
                catch (Exception e) {
                    log.error("启动流程失败", e);
                    e.printStackTrace();
                    throw new WorkFlowException("启动流程失败");
                } finally {
                    //此线程不安全 用完就需要在finally中释放
                    Authentication.setAuthenticatedUserId(null);
                }


            }
            //最后一次
            else {
                Map<String, Object> dbVariables = runtimeService.getVariables(processInstance.getId());
                Map<String, Object> variablesMap = new HashMap<>();
                variablesMap.put(FLOW_URGENT, flowModel.getFlowUrgent());
                variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());
                Map<String, List<String>> candidateList = flowModel.getCandidateList();
                if(CollUtil.isNotEmpty(candidateList)){
                    Set<String> nodeKeys = candidateList.keySet();
                    for (String nodeKey : nodeKeys) {
                        List<String> userList = candidateList.get(nodeKey);
                        variablesMap.put(nodeKey+"PointAssigneeList",userList);
                    }
                }
                runtimeService.setVariables(processInstance.getId(), variablesMap);
                //停留在发起节点了  需要手动complete
                org.flowable.task.api.Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
                List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();
                Properties firstNodeProperties = getFirstNodeProperty(task.getProcessDefinitionId());
                flowTaskUtil.circulateInitList(circulateList,flowModel,task.getId(),variablesMap,true);
                if(CollUtil.isNotEmpty(circulateList)){
                    flowTaskCirculateService.create(circulateList);
                    MsgConfig copyMsgConfig = firstNodeProperties.getCopyMsgConfig();
                    Integer on = copyMsgConfig.getOn();
                    Boolean messageFlag=false;
                    if(on!=0){
                        messageFlag=true;
                    }
                    if(messageFlag){
                        FlowMsgModel flowMsgModel = new FlowMsgModel();
                        if(CollUtil.isNotEmpty(circulateList)){
                            flowMsgModel.setCirculateList(circulateList);
                            flowMsgModel.setCopy(Boolean.TRUE);
                        }
                        flowMsgModel.setWait(Boolean.FALSE);
                        flowMsgModel.setStartNodeProperties(firstNodeProperties);
                        flowMsgModel.setCurrentNodeProperties(firstNodeProperties);
//                    flowMsgModel.setNodeList(taskNodeList);
                        List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
                        LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId());
                        FlowTaskOperatorEntity operatorServiceOne = flowTaskOperatorService.getOne(lambdaQueryWrapper);
                        operatorEntityList.add(operatorServiceOne);
                        flowMsgModel.setOperatorList(operatorEntityList);
                        flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
                        FlowTaskDTO flowTask = new FlowTaskDTO();
                        flowTask.setCreatorUserId(flowModel.getTrueAssignee());
                        flowTask.setStatus( FlowTaskStatusEnum.Handle.getCode());
                        flowTask.setFullName(MapUtil.getStr(dbVariables,BUSINESS_TITLE));
                        flowMsgModel.setTaskEntity(flowTask);

                        FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
                        flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
                        flowTaskNodeDTO.setTaskNodeId(task.getId());
                        flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);

                        flowModel.setUserInfo(UserProvider.getUser());
                        flowMsgModel.setFlowModel(flowModel);
//                    flowMsgModel.setUserInfo(UserProvider.getUser());
                        String flowId = flowModel.getFlowId();
                        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJsonNoLongText(flowId);
                        FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
                        FlowTemplateEntity template = templateAllModel.getTemplate();
                        String fullName = templateJson.getFullName();
                        flowMsgModel.setFlowTemplateAllModel(templateAllModel);
                        flowMsgModel.setTaskId(task.getProcessInstanceId());
                        flowMsgModel.setTaskNodeId(task.getId());
                        flowMsgUtil.message(flowMsgModel);
                    }
                }
                LambdaQueryWrapper<FlowTaskOperatorEntity> flowTaskOperatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
                flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId, task.getId());
                FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(flowTaskOperatorEntityLambdaQueryWrapper);
                //开始事件
//                FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
//                FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder()
//                        .status(FlowRecordEnum.submit.getCode()).flowModel(flowModel)
//                        .userId(flowModel.getTrueAssignee()).operator(operator).build();
//                flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
//                flowTaskOperatorRecordService.create(operatorRecord);
//                LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//                lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
//                FlowTaskOperatorRecordEntity operatorRecord = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
                Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
                Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
                FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
                flowTaskOperatorRecordDTO.setAssignee(flowModel.getTrueAssignee());
                flowTaskOperatorRecordDTO.setProcessInstanceId(task.getProcessInstanceId());
                flowTaskOperatorRecordDTO.setTaskId(task.getId());

                Map<String, Object> formData = flowModel.getFormData();
                formData.put("processDefinitionId",task.getProcessDefinitionId());
                formData.put("processDefinitionName",MapUtil.getStr(dbVariables,BUSINESS_TITLE));
                formData.put(BUSINESS_TITLE,MapUtil.getStr(dbVariables,BUSINESS_TITLE));
                formData.put(APPLY_USER_ID,MapUtil.getStr(dbVariables,APPLY_USER_ID));
                formData.put(BUSINESS_KEY,MapUtil.getStr(dbVariables,BUSINESS_KEY));

                //开始事件
                flowMsgUtil.event(1, firstNodeProperty, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,task.getTaskDefinitionKey());

                List<String> branchList = flowModel.getBranchList();
                if(CollUtil.isNotEmpty(branchList)){
                    runtimeService.createChangeActivityStateBuilder()
                            .processInstanceId(processInstance.getId())
                            .moveSingleActivityIdToActivityIds(task.getTaskDefinitionKey(),branchList)
                            .changeState();

                }
                else{
                    taskService.complete(task.getId());
                }

            }

            List<String> processInstanceIds= new ArrayList<>();
            processInstanceIds.add(processInstance.getId());
            FlowContextHolder.addProcessInstanceIds(processInstanceIds);
        }
        catch (Exception e){
            e.printStackTrace();
            throw new WorkFlowException("启动流程失败!");
        }
    }

    @Override
    @DSTransactional
    public void submitAllByKey(FlowModel flowModel) throws WorkFlowException {
        try {
            //进入此方法 只可能有2种情况, 先暂存,再提交,  和直接提交
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(flowModel.getProcessId()).singleResult();
            //第一次
            if (processInstance == null) {
                Map<String, Object> variablesMap = new HashMap<>();
                if (StringUtils.isNotBlank(flowModel.getDelegateUser())) {
                    variablesMap.put(DELEGATE_USER_ID, flowModel.getDelegateUser());
                }
                String flowId = flowModel.getFlowId();
                UserInfo userInfo = flowModel.getUserInfo();
                flowModel.setStatus(StringUtil.isNotEmpty(flowModel.getStatus()) ? flowModel.getStatus() : FlowStatusEnum.save.getMessage());
                flowModel.setUserId(StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId());
                //流程引擎
                FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJsonNoLongText(flowId);
                FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
                FlowTemplateEntity template = templateAllModel.getTemplate();
                String fullName = templateJson.getFullName();
                //判断
//                if (StringUtils.isBlank(templateJson.getProcessDefinitionId())) {
//                    throw new WorkFlowException("该流程属于内置数据,还没有发布!请去流程引擎页面重新发布一下!");
//                }

                String processDefinitionKey =activitiPrefix+templateJson.getGroupId();

                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processDefinitionKey).latestVersion().singleResult();
                if (processDefinition.isSuspended()) {
                    throw new WorkFlowException("流程已经挂起,请先激活!");
                }


                //流程实例
                String flowTitle = StringUtil.isNotEmpty(flowModel.getFlowTitle()) ? flowModel.getFlowTitle() : userInfo.getUserName() + "的" + fullName;
                Properties properties = getFirstNodeProperty(processDefinition.getId());
                Map<String, Object> data = flowModel.getFormData() != null ? flowModel.getFormData() : new HashMap<>();
                data.put("@flowFullName", fullName);
                data.put("@flowFullCode", template.getEnCode());
                data.put("@launchUserName", userInfo.getUserName());
                data.put("@launchTime", DateUtil.daFormat(new Date()));
                if (!FlowNature.TitleType.equals(properties.getTitleType())) {
                    flowTitle = FlowJsonUtil.field(properties.getTitleContent(), data, "1");
                }
                flowModel.setFlowTitle(flowTitle);

                variablesMap.put(BUSINESS_TITLE, flowTitle);
                variablesMap.put(PROCESS_CATEGORY, template.getCategory());
                if (StringUtils.isNotBlank(flowModel.getBillNo())) {
                    variablesMap.put(BILL_CODE, flowModel.getBillNo());
                }
                variablesMap.put(FLOW_URGENT, flowModel.getFlowUrgent());
                variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());
                variablesMap.put(APPLY_USER_ID, flowModel.getTrueAssignee());
                variablesMap.put(CURRENT_CREATE_TIME, new Date());
                variablesMap.put(BUSINESS_KEY, flowModel.getProcessId());
                variablesMap.put(FLOW_ENGINE_ID,templateJson.getTemplateId());
                variablesMap.put(FLOW_TEMPLATE_JSON_ID,templateJson.getId());
                variablesMap.put(BATCH_FLAG,templateJson.getBatch());
                Map<String, List<String>> candidateList = flowModel.getCandidateList();
                if(CollUtil.isNotEmpty(candidateList)){
                    Set<String> nodeKeys = candidateList.keySet();
                    for (String nodeKey : nodeKeys) {
                        List<String> userList = candidateList.get(nodeKey);
                        variablesMap.put(nodeKey+"PointAssigneeList",userList);
                    }
                }


                try {
                    Authentication.setAuthenticatedUserId(flowModel.getTrueAssignee());
                    processInstance = runtimeService.createProcessInstanceBuilder()
                            .processDefinitionId(processDefinition.getId())
                            .businessKey(flowModel.getProcessId())
                            .variables(variablesMap)
                            .name(flowTitle)
                            .tenantId(userInfo.getTenantId())
                            .start();


                    List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();

                    TaskEntity task = managementService.executeCommand(new FindMemoryTaskCmd(processInstance.getId()));
                    flowTaskUtil.circulateInitList(circulateList,flowModel,task.getId(),variablesMap,false);
                    if(CollUtil.isNotEmpty(circulateList)){
                        flowTaskCirculateService.create(circulateList);
                        MsgConfig copyMsgConfig = properties.getCopyMsgConfig();
                        Integer on = copyMsgConfig.getOn();
                        Boolean messageFlag=false;
                        if(on!=0){
                            messageFlag=true;
                        }
                        if(messageFlag){
                            FlowMsgModel flowMsgModel = new FlowMsgModel();
                            if(CollUtil.isNotEmpty(circulateList)){
                                flowMsgModel.setCirculateList(circulateList);
                                flowMsgModel.setCopy(Boolean.TRUE);
                            }
                            flowMsgModel.setWait(Boolean.FALSE);
                            flowMsgModel.setStartNodeProperties(properties);
                            flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
                            List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
                            LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                            lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId());
                            FlowTaskOperatorEntity operatorServiceOne = flowTaskOperatorService.getOne(lambdaQueryWrapper);
                            operatorEntityList.add(operatorServiceOne);
                            flowMsgModel.setOperatorList(operatorEntityList);
                            flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
                            FlowTaskDTO flowTask = new FlowTaskDTO();
                            flowTask.setCreatorUserId(flowModel.getTrueAssignee());
                            flowTask.setStatus( FlowTaskStatusEnum.Handle.getCode());
                            flowTask.setFullName(flowTitle);
                            flowMsgModel.setTaskEntity(flowTask);

                            FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
                            flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
                            flowTaskNodeDTO.setTaskNodeId(task.getId());
                            flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);

                            flowModel.setUserInfo(UserProvider.getUser());
                            flowMsgModel.setFlowModel(flowModel);
//                    flowMsgModel.setUserInfo(UserProvider.getUser());
                            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
                            flowMsgModel.setTaskId(task.getProcessInstanceId());
                            flowMsgModel.setTaskNodeId(task.getId());
                            flowMsgUtil.message(flowMsgModel);
                        }
                    }


//                    LambdaQueryWrapper<FlowTaskOperatorEntity> flowTaskOperatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                    flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId, task.getId());
//                    flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,flowModel.getTrueAssignee());
//                    FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(flowTaskOperatorEntityLambdaQueryWrapper);
                    //开始事件
//                    FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
//                    FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder()
//                            .status(FlowRecordEnum.submit.getCode()).flowModel(flowModel)
//                            .userId(flowModel.getTrueAssignee()).operator(operator).build();
//                    flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
//                    flowTaskOperatorRecordService.create(operatorRecord);

                    LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper= new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId, task.getId());
                    lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getHandleId,flowModel.getTrueAssignee());
                    List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(lambdaQueryWrapper);
                    for (FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity : list) {
                        flowTaskOperatorRecordEntity.setHandleTime(new Date());
                    }

                    flowTaskOperatorRecordService.updateBatchById(list);
                    Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
                    Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
                    FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
                    flowTaskOperatorRecordDTO.setAssignee(flowModel.getTrueAssignee());
                    flowTaskOperatorRecordDTO.setProcessInstanceId(task.getProcessInstanceId());
                    flowTaskOperatorRecordDTO.setTaskId(task.getId());
                    //开始事件
                    flowMsgUtil.event(1, firstNodeProperty, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,task.getTaskDefinitionKey());

                    //
                    List<String> branchList = flowModel.getBranchList();
                    if(CollUtil.isNotEmpty(branchList)){
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(processInstance.getId())
                                .moveSingleActivityIdToActivityIds(task.getTaskDefinitionKey(),branchList)
                                .changeState();

                    }
                    else{
                        taskService.complete(task.getId());
                    }



                } catch (Exception e) {
                    e.printStackTrace();
                    throw new WorkFlowException("启动流程失败");
                } finally {
                    //此线程不安全 用完就需要在finally中释放
                    Authentication.setAuthenticatedUserId(null);
                }


            }
            //最后一次
            else {
                Map<String, Object> dbVariables = runtimeService.getVariables(processInstance.getId());
                Map<String, Object> variablesMap = new HashMap<>();
                variablesMap.put(FLOW_URGENT, flowModel.getFlowUrgent());
                variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());
                Map<String, List<String>> candidateList = flowModel.getCandidateList();
                if(CollUtil.isNotEmpty(candidateList)){
                    Set<String> nodeKeys = candidateList.keySet();
                    for (String nodeKey : nodeKeys) {
                        List<String> userList = candidateList.get(nodeKey);
                        variablesMap.put(nodeKey+"PointAssigneeList",userList);
                    }
                }
                runtimeService.setVariables(processInstance.getId(), variablesMap);
                //停留在发起节点了  需要手动complete
                org.flowable.task.api.Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
                List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();
                Properties firstNodeProperties = getFirstNodeProperty(task.getProcessDefinitionId());
                flowTaskUtil.circulateInitList(circulateList,flowModel,task.getId(),variablesMap,true);
                if(CollUtil.isNotEmpty(circulateList)){
                    flowTaskCirculateService.create(circulateList);
                    MsgConfig copyMsgConfig = firstNodeProperties.getCopyMsgConfig();
                    Integer on = copyMsgConfig.getOn();
                    Boolean messageFlag=false;
                    if(on!=0){
                        messageFlag=true;
                    }
                    if(messageFlag){
                        FlowMsgModel flowMsgModel = new FlowMsgModel();
                        if(CollUtil.isNotEmpty(circulateList)){
                            flowMsgModel.setCirculateList(circulateList);
                            flowMsgModel.setCopy(Boolean.TRUE);
                        }
                        flowMsgModel.setWait(Boolean.FALSE);
                        flowMsgModel.setStartNodeProperties(firstNodeProperties);
                        flowMsgModel.setCurrentNodeProperties(firstNodeProperties);
//                    flowMsgModel.setNodeList(taskNodeList);
                        List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
                        LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId());
                        FlowTaskOperatorEntity operatorServiceOne = flowTaskOperatorService.getOne(lambdaQueryWrapper);
                        operatorEntityList.add(operatorServiceOne);
                        flowMsgModel.setOperatorList(operatorEntityList);
                        flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
                        FlowTaskDTO flowTask = new FlowTaskDTO();
                        flowTask.setCreatorUserId(flowModel.getTrueAssignee());
                        flowTask.setStatus( FlowTaskStatusEnum.Handle.getCode());
                        flowTask.setFullName(MapUtil.getStr(dbVariables,BUSINESS_TITLE));
                        flowMsgModel.setTaskEntity(flowTask);

                        FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
                        flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
                        flowTaskNodeDTO.setTaskNodeId(task.getId());
                        flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);

                        flowModel.setUserInfo(UserProvider.getUser());
                        flowMsgModel.setFlowModel(flowModel);
//                    flowMsgModel.setUserInfo(UserProvider.getUser());
                        String flowId = flowModel.getFlowId();
                        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJsonNoLongText(flowId);
                        FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
                        FlowTemplateEntity template = templateAllModel.getTemplate();
                        String fullName = templateJson.getFullName();
                        flowMsgModel.setFlowTemplateAllModel(templateAllModel);
                        flowMsgModel.setTaskId(task.getProcessInstanceId());
                        flowMsgModel.setTaskNodeId(task.getId());
                        flowMsgUtil.message(flowMsgModel);
                    }
                }
                LambdaQueryWrapper<FlowTaskOperatorEntity> flowTaskOperatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
                flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId, task.getId());
                FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(flowTaskOperatorEntityLambdaQueryWrapper);
                //开始事件
//                FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
//                FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder()
//                        .status(FlowRecordEnum.submit.getCode()).flowModel(flowModel)
//                        .userId(flowModel.getTrueAssignee()).operator(operator).build();
//                flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
//                flowTaskOperatorRecordService.create(operatorRecord);
//                LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//                lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
//                FlowTaskOperatorRecordEntity operatorRecord = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
                Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
                Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
                FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
                flowTaskOperatorRecordDTO.setAssignee(flowModel.getTrueAssignee());
                flowTaskOperatorRecordDTO.setProcessInstanceId(task.getProcessInstanceId());
                flowTaskOperatorRecordDTO.setTaskId(task.getId());

                //开始事件
                flowMsgUtil.event(1, firstNodeProperty, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,task.getTaskDefinitionKey());

                List<String> branchList = flowModel.getBranchList();
                if(CollUtil.isNotEmpty(branchList)){
                    runtimeService.createChangeActivityStateBuilder()
                            .processInstanceId(processInstance.getId())
                            .moveSingleActivityIdToActivityIds(task.getTaskDefinitionKey(),branchList)
                            .changeState();

                }
                else{
                    taskService.complete(task.getId());
                }

            }

            List<String> processInstanceIds= new ArrayList<>();
            processInstanceIds.add(processInstance.getId());
            FlowContextHolder.addProcessInstanceIds(processInstanceIds);
        }
        catch (Exception e){
            e.printStackTrace();
            throw new WorkFlowException("启动流程失败!");
        }
    }


    @Override
    public void audit(FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, FlowModel flowModel) throws WorkFlowException {
    /*    UserInfo userInfo = flowModel.getUserInfo();
        //判断是否审批过
        if (!FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
            throw new WorkFlowException("已审核完成");
        }
        //判断流程是否处于挂起状态
        flowTaskUtil.isSuspend(flowTask);
        //主流程冻结,子流程结束报错
        if (StringUtil.isNotEmpty(flowTask.getRejectId()) && StringUtil.isEmpty(operator.getReject())) {
            throw new WorkFlowException("冻结不能操作！");
        }
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowTask.getFlowId());
        boolean before = FlowNature.Before.equals(flowModel.getFreeApproverType());
        //更新表单数据
        boolean isOperator = StringUtil.isNotEmpty(operator.getId());
        boolean isUser = StringUtil.isNotEmpty(flowModel.getFreeApproverUserId());
        boolean isReject = StringUtil.isEmpty(flowTask.getRejectId());
        flowModel.setTaskOperatorId(operator.getId());
        flowModel.setParentId(isUser ? operator.getId() : flowModel.getParentId());
        flowModel.setRollbackId(before ? operator.getId() : operator.getRollbackId());
        flowModel.setRejectUser(StringUtil.isNotEmpty(flowTask.getRejectId()) ? true : false);
        FlowTaskNodeEntity flowTaskNode = flowTaskNodeService.getInfo(operator.getTaskNodeId(),
                FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getTaskId, FlowTaskNodeEntity::getFormId, FlowTaskNodeEntity::getNodeType,
                FlowTaskNodeEntity::getNodePropertyJson, FlowTaskNodeEntity::getSortCode, FlowTaskNodeEntity::getNodeCode,
                FlowTaskNodeEntity::getNodeNext, FlowTaskNodeEntity::getCandidates
        );
        //自动审批获取最新表单数据
        Map<String, Object> formData = flowModel.getVoluntarily() ? flowTaskUtil.infoData(flowTaskNode.getFormId(), flowTask.getId()) : flowModel.getFormData();
        if (!FlowNature.NodeSubFlow.equals(flowTaskNode.getNodeType())) {
            FlowContextHolder.addData(flowTaskNode.getFormId(), formData);
            FlowContextHolder.addChildData(flowTask.getId(), flowTaskNode.getFormId(), formData);
            ChildNodeList nodeModel = JsonUtil.getJsonToBean(flowTaskNode.getNodePropertyJson(), ChildNodeList.class);
            List<Map<String, Object>> formOperates = flowTaskUtil.formOperates(nodeModel);
            FlowContextHolder.addFormOperates(flowTask.getId(), flowTaskNode.getFormId(), formOperates);
        }
        //todo
        if (!flowModel.getIsAsync() && isReject) {
            flowTaskUtil.auditTaskNode(templateAllModel, flowTask, flowTaskNode, flowModel);
        }
        //流程所有节点
        TaskNodeListModel taskNodeListModel = TaskNodeListModel.builder().id(flowTask.getId()).state(FlowNodeEnum.Process.getCode()).build();
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(taskNodeListModel,
                FlowTaskNodeEntity::getFormId, FlowTaskNodeEntity::getNodeType, FlowTaskNodeEntity::getSortCode,
                FlowTaskNodeEntity::getNodeCode, FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getNodePropertyJson,
                FlowTaskNodeEntity::getNodeNext, FlowTaskNodeEntity::getNodeName, FlowTaskNodeEntity::getCompletion,
                FlowTaskNodeEntity::getTaskId, FlowTaskNodeEntity::getState, FlowTaskNodeEntity::getCandidates,
                FlowTaskNodeEntity::getNodeUp
        );
        //当前节点
        FlowTaskNodeEntity taskNode = taskNodeList.stream().filter(m -> m.getId().equals(operator.getTaskNodeId())).findFirst().orElse(null);
        if (taskNode == null) {
            throw new WorkFlowException(MsgCode.COD001.get());
        }
        //加签回流
        if (!isUser) {
            String rollbackId = StringUtil.isNotEmpty(operator.getRollbackId()) ? operator.getRollbackId() : RandomUtil.uuId();
            FlowTaskOperatorEntity operatorInfo = flowTaskOperatorService.getOperatorInfo(rollbackId);
            if (operatorInfo != null) {
                FlowModel rollbackModel = new FlowModel();
                rollbackModel.setUserInfo(flowModel.getUserInfo());
                rollbackModel.setTaskOperatorId(flowModel.getTaskOperatorId());
                rollbackModel.setParentId(flowModel.getTaskOperatorId());
                rollbackModel.setCopyIds(flowModel.getCopyIds());
                rollbackModel.setFileList(flowModel.getFileList());
                rollbackModel.setHandleOpinion(flowModel.getHandleOpinion());
                rollbackModel.setSignImg(flowModel.getSignImg());
                rollbackModel.setRejectUser(flowModel.getRejectUser());
                rollbackModel.setFormData(flowModel.getFormData());
                flowModel = JsonUtil.getJsonToBean(rollbackModel, FlowModel.class);
                flowModel.setFreeApproverUserId(operatorInfo.getHandleId());
                flowModel.setRollbackId(operatorInfo.getRollbackId());
                flowModel.setFreeApproverType(FlowNature.Reflux);
                flowModel.setTaskOperatorId(FlowNature.ParentId.equals(operatorInfo.getParentId()) ? FlowNature.ParentId : flowModel.getTaskOperatorId());
            }
        }
        String userId = StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId();
        //当前节点属性
        ChildNodeList nodeModel = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
        //修改或签、会签经办数据
        TaskHandleIdStatus handleIdStatus = new TaskHandleIdStatus();
        handleIdStatus.setStatus(1);
        handleIdStatus.setNodeModel(nodeModel);
        handleIdStatus.setUserInfo(userInfo);
        handleIdStatus.setTaskNodeList(taskNodeList);
        handleIdStatus.setFlowModel(flowModel);
        flowTaskUtil.handleIdStatus(operator, handleIdStatus);
        //更新流当前程经办状态
        if (isOperator) {
            operator.setState(StringUtil.isNotEmpty(flowModel.getFreeApproverUserId()) ? FlowNodeEnum.FreeApprover.getCode() : operator.getState());
            flowTaskOperatorService.update(operator);
        }
        //更新下一节点
        List<FlowTaskOperatorEntity> operatorList = new ArrayList<>();
        //获取下一审批人
        List<FlowTaskNodeEntity> nextNode = taskNodeList.stream().filter(t -> taskNode.getNodeNext().contains(t.getNodeCode())).collect(Collectors.toList());
        //判断转向节点是否错误
        String msg = "";
        List<FlowTaskNodeEntity> flowTaskNodeEntities = JsonUtil.getJsonToList(taskNodeList, FlowTaskNodeEntity.class);
        flowTaskUtil.nodeList(flowTaskNodeEntities);
        List<String> nextNodeCode = nextNode.stream().map(FlowTaskNodeEntity::getNodeCode).collect(Collectors.toList());
        boolean isNotNode = flowTaskNodeEntities.stream().filter(t -> nextNodeCode.contains(t.getNodeCode())).count() == 0;
        if (isNotNode) {
            nextNodeCode.add(taskNode.getNodeNext());
            TaskNodeListModel taskNodeModel = TaskNodeListModel.builder().id(flowTask.getId()).build();
            List<FlowTaskNodeEntity> nodeList = flowTaskNodeService.getList(taskNodeModel, FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getNodeCode);
            boolean isErrorNode = nodeList.stream().filter(t -> nextNodeCode.contains(t.getNodeCode())).count() == 0;
            msg = isErrorNode ? "转向节点不存在或配置错误" : "转向失败，转向节点未审批";
            nextNode.add(taskNode);
        }
        List<ChildNodeList> nextOperatorList = new ArrayList<>();
        FlowNextModel flowNextModel = FlowNextModel.builder().nodeListAll(taskNodeList).nextNodeEntity(nextNode).taskNode(taskNode).flowModel(flowModel).isCountersign(false).build();
        List<FlowTaskNodeEntity> result = flowTaskUtil.isNextAll(flowNextModel);
        flowTaskUtil.candidateList(flowModel, taskNodeList, operator);
        if (result.size() > 0) {
            if (StringUtil.isNotEmpty(msg)) {
                throw new WorkFlowException(msg);
            }
            boolean freeApproverUserId = StringUtil.isEmpty(flowModel.getFreeApproverUserId());
            if (freeApproverUserId && !isReject) {
                FlowRejectDataEntity info = flowRejectDataService.getInfo(flowTask.getRejectId());
                FlowTaskEntity jsonToBean = JsonUtil.getJsonToBean(info.getTaskJson(), FlowTaskEntity.class);
                jsonToBean.setRejectId(null);
                flowTask.setRejectId(null);
                flowModel.setRejectUser(false);
                flowTaskService.update(jsonToBean);
                Set<String> rejectNodeList = new HashSet<>();
                List<String> rejectList = new ArrayList() {{
                    add(operator.getTaskNodeId());
                }};
                List<String> thisStepId = Arrays.asList(jsonToBean.getThisStepId().split(","));
                List<FlowTaskNodeEntity> rejectTaskNodeList = JsonUtil.getJsonToList(info.getTaskNodeJson(), FlowTaskNodeEntity.class);
                flowTaskUtil.upAll(rejectNodeList, rejectList, rejectTaskNodeList);
                for (FlowTaskNodeEntity taskNodeEntity : rejectTaskNodeList) {
                    FlowTaskNodeEntity node = taskNodeList.stream().filter(t -> t.getId().equals(taskNodeEntity.getId())).findFirst().orElse(null);
                    taskNodeEntity.setDraftData(node != null ? JsonUtil.getObjectToString(flowModel.getFormData()) : taskNodeEntity.getDraftData());
                    flowTaskNodeService.update(taskNodeEntity);
                    taskNodeEntity.setNodePropertyJson(node != null ? node.getNodePropertyJson() : "{}");
                }
                //获取
                List<FlowTaskNodeEntity> rejectNodeAll = rejectTaskNodeList.stream().filter(t -> rejectNodeList.contains(t.getId())).collect(Collectors.toList());
                for (FlowTaskNodeEntity taskNodeEntity : rejectNodeAll) {
                    if (thisStepId.contains(taskNodeEntity.getNodeCode())) {
                        nextOperatorList.add(JsonUtil.getJsonToBean(taskNodeEntity.getNodePropertyJson(), ChildNodeList.class));
                    }
                }
                //还原审批数据状态
                List<FlowTaskOperatorEntity> operatorEntityList = JsonUtil.getJsonToList(info.getTaskOperatorJson(), FlowTaskOperatorEntity.class);
                for (FlowTaskOperatorEntity flowTaskOperatorEntity : operatorEntityList) {
                    flowTaskOperatorService.update(flowTaskOperatorEntity);
                }
                //冻结数据传递
                flowTaskUtil.dataAssignment(operator.getTaskNodeId(), rejectTaskNodeList, flowModel);
            } else {
                //分支的下个节点
                List<FlowTaskNodeEntity> nodeCandidateList = result.stream().filter(t -> StringUtil.isNotEmpty(t.getCandidates())).collect(Collectors.toList());
                for (FlowTaskNodeEntity entity : nodeCandidateList) {
                    ChildNodeList node = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                    nextOperatorList.add(node);
                }
                if (nextOperatorList.size() == 0) {
                    for (FlowTaskNodeEntity entity : result) {
                        ChildNodeList node = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                        nextOperatorList.add(node);
                    }
                }
            }
        }
        boolean isStart = nextNode.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).count() > 0;
        boolean isCompletion = nextNode.stream().filter(t -> FlowNature.AuditCompletion.equals(t.getCompletion())).count() > 0;
        boolean isSwerve = flowNextModel.getIsCountersign() && isCompletion;
        //同意记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(isSwerve ? FlowRecordEnum.swerve.getCode() : FlowRecordEnum.audit.getCode()).flowModel(flowModel).userId(userId).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        //子流程不新增流转记录
        if (!flowModel.getIsAsync() && !before) {
            flowTaskUtil.createRecord(operatorRecord);
        }
        if (isReject) {
            //更新流程节点
            if (isSwerve) {
                FlowTaskNodeEntity serverTaskNode = new FlowTaskNodeEntity();
                serverTaskNode.setNodeUp(taskNode.getNodeNext());
                serverTaskNode.setTaskId(serverTaskNode.getTaskId());
                FlowUpModel flowUpModel = FlowUpModel.builder().flowTask(flowTask).taskNode(serverTaskNode).taskNodeList(taskNodeList)
                        .isReject(isSwerve).rejectType(true).flowModel(flowModel).isAudit(true).build();
                flowTaskUtil.flowUp(flowUpModel);
            } else {
                flowTaskUtil.getNextStepId(nextOperatorList, flowTask, flowModel, taskNodeList);
                flowTask.setCompletion(FlowNature.NodeEnd.equals(flowTask.getThisStepId()) ? FlowNature.Progress : flowTask.getCompletion());
            }
            if (StringUtil.isNotEmpty(flowTask.getThisStepId())) {
                FlowTaskEntity updateFlowTask = new FlowTaskEntity();
                updateFlowTask.setTaskNodeId(null);
                updateFlowTask.setCompletion(flowTask.getCompletion());
                updateFlowTask.setThisStepId(flowTask.getThisStepId());
                updateFlowTask.setStatus(flowTask.getStatus());
                updateFlowTask.setThisStep(flowTask.getThisStep());
                updateFlowTask.setId(flowTask.getId());
                flowTaskService.update(updateFlowTask);
            }
        }
        //下个节点
        Map<String, List<String>> asyncTaskList = new HashMap<>();
        Map<String, List<String>> nodeTaskIdList = new HashMap<>();
        FlowOperator flowOperator = FlowOperator.builder().operatorListAll(operatorList).flowModel(flowModel).flowTask(flowTask).nodeList(nextOperatorList).taskNodeListAll(taskNodeList).userInfo(userInfo).asyncTaskList(asyncTaskList).nodeTaskIdList(nodeTaskIdList).build();
        if (!isStart) {
            flowTaskUtil.nextOperator(flowOperator);
            Map<String, List<FlowTaskOperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId));
            for (ChildNodeList childNodeList : nextOperatorList) {
                Properties properties = childNodeList.getProperties();
                boolean counterSign = FlowNature.ImproperApprover.equals(properties.getCounterSign());
                if (counterSign && StringUtil.isEmpty(flowModel.getFreeApproverUserId())) {
                    List<FlowTaskOperatorEntity> listAll = operatorMap.get(childNodeList.getTaskNodeId()) != null ? operatorMap.get(childNodeList.getTaskNodeId()) : new ArrayList<>();
                    flowOperatorUserService.create(JsonUtil.getJsonToList(listAll, FlowOperatorUserEntity.class));
                }
                FlowDataModel flowDataModel = new FlowDataModel(childNodeList, taskNodeList, flowModel, true, true);
                flowTaskUtil.createOrUpdate(flowDataModel);
            }
            //过滤依次审批人
            if (StringUtil.isEmpty(flowModel.getFreeApproverUserId())) {
                flowTaskUtil.improperApproverUser(operatorList, taskNodeList, nodeModel, operator);
            }
            flowTaskUtil.timer(operator, taskNodeList, operatorList);
            flowTaskOperatorService.create(operatorList);
            //修改选择分支没有走过的节点
            if (flowModel.getBranchList().size() > 0) {
                List<String> nodeCodeList = result.stream().map(FlowTaskNodeEntity::getNodeCode).collect(Collectors.toList());
                flowTaskUtil.branchTaskNode(nodeCodeList, taskNodeList, operatorList);
            }
        }
        //更新关联同步子流程id
        for (String nodeId : nodeTaskIdList.keySet()) {
            FlowTaskNodeEntity entity = taskNodeList.stream().filter(t -> t.getId().equals(nodeId)).findFirst().orElse(null);
            if (entity != null) {
                ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                childNodeList.getCustom().setTaskId(nodeTaskIdList.get(nodeId));
                entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
                flowTaskNodeService.updateTaskIdList(entity);
            }
        }
        //更新关联异步子流程id
        for (String nodeId : asyncTaskList.keySet()) {
            FlowTaskNodeEntity entity = taskNodeList.stream().filter(t -> t.getId().equals(nodeId)).findFirst().orElse(null);
            if (entity != null) {
                ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
                childNodeList.getCustom().setAsyncTaskList(asyncTaskList.get(nodeId));
                entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
                flowTaskNodeService.updateTaskIdList(entity);
            }
        }
        //获取抄送人
        List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();
        if (isReject) {
            flowTaskUtil.circulateList(nodeModel, taskNodeList, circulateList, flowModel, flowTask);
            flowTaskCirculateService.create(circulateList);
        }
        //更新节点接收时间
        flowTaskUtil.taskCreatTime(operatorList);
        //委托消息
        boolean approve = StringUtil.isNotEmpty(flowTask.getDelegateUser());
        if (approve) {
            FlowDelegateModel delegate = new FlowDelegateModel();
            delegate.setToUserIds(ImmutableList.of(operator.getHandleId()));
            delegate.setDelegate(false);
            delegate.setType(FlowNature.ApproveMsg);
            delegate.setUserInfo(userInfo);
            delegate.setFlowTask(flowTask);
            delegate.setTemplateAllModel(templateAllModel);
            delegate.setApprove(approve);
            flowMsgUtil.delegateMsg(delegate);
        }
        if (isReject) {
            //节点事件
            flowMsgUtil.event(4, nodeModel, operatorRecord, flowModel);
            //发送消息
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            flowMsgModel.setApprove(FlowNature.AuditCompletion.equals(taskNode.getCompletion()));
            flowMsgModel.setCopy(true);
            flowMsgModel.setNodeList(taskNodeList);
            flowMsgModel.setOperatorList(operatorList);
            flowMsgModel.setCirculateList(circulateList);
            flowMsgModel.setData(flowModel.getFormData());
            flowMsgModel.setTaskNodeEntity(taskNode);
            flowMsgModel.setTaskEntity(flowTask);
            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
            FlowTaskOperatorRecordEntity taskOperatorRecord = new FlowTaskOperatorRecordEntity();
            taskOperatorRecord.setHandleId(userInfo.getUserId());
            flowMsgModel.setFlowModel(flowModel);
            flowMsgUtil.message(flowMsgModel);
            //超时
            insTimeOutRedis(flowModel, operatorList, userInfo, flowTask, taskNodeList);
            //自动审批
            if (!isSwerve) {
                FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorList).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).build();
                flowTaskUtil.approve(approveModel);
                //查询代办用户是否通过
                flowTaskUtil.approverPass(flowTask, taskNodeList, flowModel, operator);
            }
        }*/
    }

    @Override
    public ActionResult<Boolean> auditAll(FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, FlowModel flowModel) throws WorkFlowException {
        try {
            activitiUtils.validProcessStatus(operator.getTaskId());
            UserInfo userInfo = flowModel.getUserInfo();
            org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(operator.getTaskNodeId()).includeProcessVariables().singleResult();
            Map<String, Object> processVariables = task.getProcessVariables();
            if(StringUtils.isBlank(task.getParentTaskId())){
                //不是子任务, 判断是不是前加签任务
                String taskDefinitionKey = task.getTaskDefinitionKey();
                if(taskDefinitionKey.startsWith(ADD_MULTI_NODE_PREFIX)){
//                    Flow
                }

                String templateJsonId = MapUtil.getStr(processVariables, FLOW_TEMPLATE_JSON_ID);
                FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(templateJsonId);
                //1.2调用事件
                Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
                String property = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, task.getTaskDefinitionKey(), "userTask");
                Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {});
                List<FlowTaskCirculateEntity> flowTaskCirculateEntities =new ArrayList<>();
                //1.0处理抄送
                String copyIds = flowModel.getCopyIds();

                if(StringUtils.isNotBlank(copyIds)){
                    String[] split = copyIds.split(",");
                    List<String> arr = Arrays.asList(split);
                    for (String s : arr) {
                        FlowTaskCirculateEntity circulate = new FlowTaskCirculateEntity();
                        circulate.setId(RandomUtil.uuId());
                        circulate.setObjectId(s);
                        circulate.setNodeCode(task.getTaskDefinitionKey());
                        circulate.setNodeName(task.getName());
                        circulate.setTaskNodeId(task.getId());
                        circulate.setTaskId(task.getProcessInstanceId());
                        circulate.setCreatorTime(new Date());
                        circulate.setEnCode(MapUtil.getStr(processVariables,BILL_CODE));
                        circulate.setFullName(MapUtil.getStr(processVariables,BUSINESS_TITLE));
                        circulate.setTemplateId(MapUtil.getStr(processVariables,FLOW_ENGINE_ID));
                        circulate.setFlowId(MapUtil.getStr(processVariables,FLOW_TEMPLATE_JSON_ID));
                        circulate.setFlowCategory(MapUtil.getStr(processVariables,PROCESS_CATEGORY));
                        circulate.setFlowUrgent(MapUtil.getInt(processVariables,FLOW_URGENT));
                        circulate.setCreatorTime(new Date());
                        String applyUserId = MapUtil.getStr(processVariables, APPLY_USER_ID);
                        UserEntity info = userService.getInfo(applyUserId);
                        circulate.setApplyUserId(info.getRealName()+"/"+info.getAccount());
                        circulate.setApplyUserIdReal(applyUserId);
                        circulate.setProcessStatus(MapUtil.getInt(processVariables,PROCESS_STATUS));
                        flowTaskCirculateEntities.add(circulate);
                    }
                    flowTaskCirculateService.create(flowTaskCirculateEntities);



                }
                FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity=null;
                //委派任务处理
                if(DelegationState.PENDING.equals(task.getDelegationState())){
                    taskService.resolveTask(task.getId());
//                LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper= new LambdaQueryWrapper<>();
//                lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId()).eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
//                FlowTaskOperatorEntity flowTaskOperatorEntity = flowTaskOperatorService.getOne(lambdaQueryWrapper);
                    //修改经办记录状态
                    LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId()).eq(FlowTaskOperatorRecordEntity::getHandleId,userInfo.getUserId());
                    FlowTaskOperatorRecordEntity operatorRecordServiceOne = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);

                    operatorRecordServiceOne.setHandleStatus(FlowRecordEnum.DELEGATE_TASK.getCode());
                    operatorRecordServiceOne.setHandleTime(new Date());
                    operatorRecordServiceOne.setHandleOpinion(flowModel.getHandleOpinion());
                    operatorRecordServiceOne.setSignImg(flowModel.getSignImg());
                    operatorRecordServiceOne.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
                    flowTaskOperatorRecordService.updateById(operatorRecordServiceOne);
                    //当前任务经办更新
                    flowTaskOperatorRecordEntity=operatorRecordServiceOne;
                    return ActionResult.success("完成委派任务成功!");
                }
                else{
                    //更新经办状态同意
                    LambdaQueryWrapper<FlowTaskOperatorRecordEntity> flowTaskOperatorRecordEntityLambdaQueryWrapper= new LambdaQueryWrapper<>();
                    flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,operator.getId());
                    flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(flowTaskOperatorRecordEntityLambdaQueryWrapper);
                    flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.audit.getCode());
                    flowTaskOperatorRecordEntity.setHandleTime(new Date());
                    flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
                    flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
                    flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
                    flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);
                }

                List<String> branchList = flowModel.getBranchList();
                //候选人处理
                Map<String, List<String>> candidateList = flowModel.getCandidateList();
                Map<String,Object> variablesMap = new HashMap<>();
                variablesMap.put(PROCESS_STATUS,FlowTaskStatusEnum.Handle.getCode());
                if(CollUtil.isNotEmpty(candidateList)){
                    Set<String> nodeKeys = candidateList.keySet();
                    for (String nodeKey : nodeKeys) {
                        List<String> userList = candidateList.get(nodeKey);
                        variablesMap.put(nodeKey+"PointAssigneeList",userList);
                    }
                }
                runtimeService.setVariables(task.getProcessInstanceId(),variablesMap);

                String formKey = task.getFormKey();
                String[] formKeySplit = formKey.split(taskDescriptionSeparator);


                Integer commentType = properties.getCommentType();
                Map<String, Object> data = flowModel.getFormData();
                if(commentType!=null && commentType.equals(1)){
                    FlowTemplateEntity template = templateAllModel.getTemplate();
                    data.put("@flowFullName", template.getFullName());
                    data.put("@flowFullCode", template.getEnCode());
                    data.put("@launchUserName", MapUtil.getStr(processVariables,APPLY_USER_NAME));
                    data.put("@launchTime", task.getCreateTime());
                    data.put("@currentNodeComment",flowModel.getHandleOpinion());
                    data.put("@currentNodeComment",flowModel.getHandleOpinion());
                    data.put("@currentNodeName",task.getName());
                    data.put("@currentNodeUserName",userInfo.getUserName());
                    data.put("@auditTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern(DateTimeFormatConstant.YEAR_MOnTH_DATE)));
                    String field = FlowJsonUtil.field(properties.getCommentContent(), data, "1");
                    data.put(properties.getCommentField(),field);
                }

                //禁用签名
                Integer signType = properties.getSignType();
                if(signType!=null && signType.equals(1) && flowModel.getSignImg()!=null){
                    data.put(properties.getSignField(),flowModel.getSignImg());
                }


                FlowFormDataModel model = FlowFormDataModel.builder().formId(formKeySplit[0]).id(formKeySplit[1]).map(flowModel.getFormData()).formOperates(properties.getFormOperates()).build();
                FlowContextHolder.addData(formKeySplit[1], flowModel.getFormData());
                serviceUtil.createOrUpdate(model);

                //通过事件处理
                FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
                flowTaskOperatorRecordDTO.setAssignee(flowTaskOperatorRecordEntity.getHandleId());
                flowTaskOperatorRecordDTO.setProcessInstanceId(flowTaskOperatorRecordEntity.getTaskId());
                flowTaskOperatorRecordDTO.setTaskId(flowTaskOperatorRecordEntity.getTaskNodeId());
                flowMsgUtil.event(4, properties, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,task.getTaskDefinitionKey());

                //1.3调用通知
                Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
                MsgConfig copyMsgConfig = properties.getCopyMsgConfig();
                Integer msgConfigOnn = copyMsgConfig.getOn();

                Boolean messageFlag=false;
                if(msgConfigOnn!=0){
                    if(msgConfigOnn==2){
                        if(firstNodeProperty.getCopyMsgConfig().getOn()!=0){
                            messageFlag=true;
                        }
                    }
                    else{
                        messageFlag=true;
                    }
                }

                if(messageFlag){
                    FlowMsgModel flowMsgModel = new FlowMsgModel();
                    if(CollUtil.isNotEmpty(flowTaskCirculateEntities)){
                        flowMsgModel.setCirculateList(flowTaskCirculateEntities);
                        flowMsgModel.setCopy(Boolean.TRUE);
                    }
                    flowMsgModel.setWait(Boolean.FALSE);
                    flowMsgModel.setApprove(Boolean.FALSE);
                    flowMsgModel.setStartNodeProperties(firstNodeProperty);
                    flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
                    List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
                    operatorEntityList.add(operator);
                    flowMsgModel.setOperatorList(operatorEntityList);
                    flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
                    FlowTaskDTO flowTaskDTO = new FlowTaskDTO();

                    flowTaskDTO.setCreatorUserId(MapUtil.getStr(processVariables,APPLY_USER_ID));
                    flowTaskDTO.setStatus(MapUtil.getInt(processVariables,PROCESS_STATUS));
                    flowTaskDTO.setFullName(MapUtil.getStr(processVariables,BUSINESS_TITLE));
                    flowMsgModel.setTaskEntity(flowTaskDTO);

                    FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
                    flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
                    flowTaskNodeDTO.setTaskNodeId(task.getId());
                    flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);
                    flowModel.setUserInfo(UserProvider.getUser());
                    flowMsgModel.setFlowModel(flowModel);
                    flowMsgModel.setFlowTemplateAllModel(templateAllModel);
                    flowMsgModel.setTaskId(task.getProcessInstanceId());
                    flowMsgModel.setTaskNodeId(task.getId());
                    flowMsgUtil.message(flowMsgModel);
                }
                //不设置 priority 固定的
//            taskService.setVariableLocal(task.getId(), TaskVariableConstants.TASK_STATE,FlowRecordEnum.audit.getCode())
//            //判断是不是选择分支, 如果是选择分支, 那么直接跳走;
                if(CollUtil.isNotEmpty(branchList)){
                    List<String> activeActivityIds = runtimeService.getActiveActivityIds(task.getProcessInstanceId());
                    ArrayList<String> distinct = CollUtil.distinct(activeActivityIds);
                    if(branchList.size()>1){
                        if(distinct.size()>1){
                            throw new WorkFlowException("不支持多对多审批链路跳转,需要修改节点基础设置!!");
                        }
                        else{
                            runtimeService.createChangeActivityStateBuilder()
                                    .processInstanceId(task.getProcessInstanceId())
                                    .moveSingleActivityIdToActivityIds(task.getTaskDefinitionKey(),branchList)
                                    .changeState();
                        }
                    }
                    else{
                        List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(task.getProcessInstanceId())
                                .moveExecutionsToSingleActivityId(mainExecutions,branchList.get(0))
                                .changeState();
                    }
                }
                else{
                    String rejectNode = MapUtil.getStr(processVariables, REJECT_NODE);
                    if(StringUtils.isBlank(rejectNode)){
                        String rollbackId = StringUtil.isNotEmpty(operator.getRollbackId()) ? operator.getRollbackId() : RandomUtil.uuId();
                        FlowTaskOperatorEntity operatorInfo = flowTaskOperatorService.getOperatorInfo(rollbackId);
                        Integer counterSign = properties.getCounterSign();
                        //说明加过签,回到加签人位置
                        if(operatorInfo!=null){
                            if(counterSign==0 || counterSign==1){
                                String taskNodeId = operatorInfo.getTaskNodeId();
                                long count = taskService.createTaskQuery().taskId(taskNodeId).count();
                                if(count>0){
                                    managementService.executeCommand(new ActiveTaskCmd(taskNodeId));
                                    taskService.complete(task.getId());
                                }
                            }
                            else if(counterSign==2){
                                String handleId = operatorInfo.getHandleId();
                                String executionId = task.getExecutionId();
                                String variableName = taskDefinitionKey + "assigneeList";
                                List assigneeUserList = runtimeService.getVariable(executionId, variableName, List.class);
                                assigneeUserList.add(handleId);
                                runtimeService.setVariable(executionId,variableName,assigneeUserList);
                                Map<String,Object> variableMap= new HashMap<>();
                                variableMap.put("assignee",handleId);
                                ExecutionEntity execution = (ExecutionEntity) runtimeService.addMultiInstanceExecution(task.getTaskDefinitionKey(), task.getProcessInstanceId(), variableMap);
                                taskService.complete(task.getId());
                            }

                        }
                        else{
                            String executionId = managementService.executeCommand(new GetExecutionEntityManagerCmd(task.getExecutionId()));
                            if(counterSign.equals(0)){
                                runtimeService.setVariable(executionId,COUNTER_SIGN_COMPLETE,Boolean.TRUE);
                            }
                            Object variable = runtimeService.getVariable(executionId, MULTI_INSTANCE_NUM_AUDIT);
                            if(variable==null){
                                runtimeService.setVariable(executionId,MULTI_INSTANCE_NUM_AUDIT,1);
                            }
                            else{
                                Integer num=(Integer)variable;
                                runtimeService.setVariable(executionId,MULTI_INSTANCE_NUM_AUDIT,num+1);
                            }
                            //
                            LambdaQueryWrapper<FlowRunAddNodeTemplateEntity> lambdaQueryWrapper  =new LambdaQueryWrapper<>();
                            lambdaQueryWrapper.eq(FlowRunAddNodeTemplateEntity::getProcessInstanceId,task.getProcessInstanceId());
                            lambdaQueryWrapper.eq(FlowRunAddNodeTemplateEntity::getFirstId,task.getTaskDefinitionKey());
                            lambdaQueryWrapper.orderByDesc(FlowRunAddNodeTemplateEntity::getCreatorTime);
                            IPage page= new Page();
                            page.setCurrent(0);
                            page.setSize(1);
                            IPage<FlowRunAddNodeTemplateEntity> page1 = flowRunAddNodeTemplateEntityService.page(page, lambdaQueryWrapper);
                            List<FlowRunAddNodeTemplateEntity> records = page1.getRecords();
                            if(CollUtil.isEmpty(records)){
                                taskService.complete(task.getId());
                            }
                            else{
                            }


                        }
                    }
                    else{
                        runtimeService.removeVariable(task.getProcessInstanceId(),REJECT_NODE);
                        String[] split = rejectNode.split(",");
                        List<String> rejectList = Arrays.asList(split);
                        List<String> activeActivityIds = runtimeService.getActiveActivityIds(task.getProcessInstanceId());
                        ArrayList<String> distinct = CollUtil.distinct(activeActivityIds);
                        if(rejectList.size()>1){
                            if(distinct.size()>1){
                                throw new WorkFlowException("不支持多对多审批链路跳转,需要修改节点基础设置!!");
                            }
                            else{
                                runtimeService.createChangeActivityStateBuilder()
                                        .processInstanceId(task.getProcessInstanceId())
                                        .moveSingleActivityIdToActivityIds(task.getTaskDefinitionKey(),rejectList)
                                        .changeState();
                            }
                        }
                        else{
                            String rejectTaskProperty = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, rejectNode, "userTask");
                            Properties rejectProperties = JSONObject.parseObject(rejectTaskProperty, new TypeReference<Properties>() {
                            });
                            String targetBranchFlowId = rejectProperties.getBranchFlowId();
                            String branchFlowId = properties.getBranchFlowId();

                            if(StringUtils.isNotBlank(branchFlowId)){
                                if(branchFlowId.equals(targetBranchFlowId)){
                                    runtimeService.createChangeActivityStateBuilder()
                                            .processInstanceId(task.getProcessInstanceId())
                                            .moveActivityIdTo(task.getTaskDefinitionKey(),rejectNode)
                                            .changeState();
                                }
                                else{
                                    List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                                    runtimeService.createChangeActivityStateBuilder()
                                            .processInstanceId(task.getProcessInstanceId())
                                            .moveExecutionsToSingleActivityId(mainExecutions,rejectNode)
                                            .changeState();
                                }
                            }
                            else{
                                List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                                runtimeService.createChangeActivityStateBuilder()
                                        .processInstanceId(task.getProcessInstanceId())
                                        .moveExecutionsToSingleActivityId(mainExecutions,rejectNode)
                                        .changeState();
                            }
                        }
                    }
                }
            }
            else{
                LambdaQueryWrapper<FlowTaskOperatorRecordEntity> flowTaskOperatorRecordEntityLambdaQueryWrapper= new LambdaQueryWrapper<>();
                flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,operator.getId());
                FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(flowTaskOperatorRecordEntityLambdaQueryWrapper);
                flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.audit.getCode());
                flowTaskOperatorRecordEntity.setHandleTime(new Date());
                flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
                flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
                flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
                flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);
                taskService.complete(operator.getTaskNodeId());
            }

            return ActionResult.success("审核成功");
        }
        catch (WorkFlowException e){
            throw new WorkFlowException(e.getMessage());
        }
        catch (Exception e){
            e.printStackTrace();
            log.error("同意审核失败 param -> {} -> error: {}", JSONObject.toJSONString(flowTask), e);
            throw new WorkFlowException("同意审核失败");
        }
    }

    @Override
    @DSTransactional
    public void audit(FlowModel flowModel) throws WorkFlowException {
        String id = flowModel.getId();
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
        UserInfo userInfo = userProvider.get();
        flowModel.setUserInfo(userInfo);
        FlowTaskEntity flowTask = flowTaskService.getInfo(operator.getTaskId(),
                FlowTaskEntity::getStatus, FlowTaskEntity::getTemplateId, FlowTaskEntity::getFlowId,
                FlowTaskEntity::getId, FlowTaskEntity::getFullName, FlowTaskEntity::getCreatorUserId,
                FlowTaskEntity::getParentId, FlowTaskEntity::getThisStepId, FlowTaskEntity::getThisStep,
                FlowTaskEntity::getRejectId, FlowTaskEntity::getCompletion
        );
        permissions(operator.getHandleId(), flowTask, operator, "", flowModel);
        if (!FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
            throw new WorkFlowException("已审核完成");
        }
        if (FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
            auditAll(flowTask, operator, flowModel);
        }
    }

    @Override
    @DSTransactional
    public void reject(FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, FlowModel flowModel) throws WorkFlowException {
   /*     UserInfo userInfo = flowModel.getUserInfo();
        String userId = StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId();
        List<String> rejectThisStepId = Arrays.asList(flowTask.getThisStepId().split(","));
        //判断流程是否处于挂起状态
        flowTaskUtil.isSuspend(flowTask);
        //流程所有节点
        TaskNodeListModel taskNodeListModel = TaskNodeListModel.builder().id(flowTask.getId()).state(FlowNodeEnum.Process.getCode()).build();
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(taskNodeListModel,
                FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getTaskId, FlowTaskNodeEntity::getNodePropertyJson,
                FlowTaskNodeEntity::getNodeNext, FlowTaskNodeEntity::getNodeCode, FlowTaskNodeEntity::getNodeName,
                FlowTaskNodeEntity::getNodeType, FlowTaskNodeEntity::getFormId, FlowTaskNodeEntity::getState,
                FlowTaskNodeEntity::getCompletion
        );
        List<FlowTaskOperatorEntity> operatorEntityList = flowTaskOperatorService.getList(flowTask.getId()).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState()) && !rejectThisStepId.contains(t.getNodeCode())).collect(Collectors.toList());
        //保存当前节点和任务
        String taskJson = JsonUtil.getObjectToString(JsonUtil.getJsonToBean(flowTask, FlowTaskRejectModel.class));
        String taskNodeJson = JsonUtil.getObjectToString(JsonUtil.getJsonToList(taskNodeList, FlowTaskNodeRejectModel.class));
        //当前节点
        Optional<FlowTaskNodeEntity> first = taskNodeList.stream().filter(m -> m.getId().equals(operator.getTaskNodeId())).findFirst();
        if (!first.isPresent()) {
            throw new WorkFlowException(MsgCode.COD001.get());
        }
        FlowTaskNodeEntity taskNode = first.get();
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowTask.getFlowId());
        flowTaskUtil.candidateList(flowModel, taskNodeList, operator);
        //当前节点属性
        ChildNodeList nodeModel = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
        boolean rejectType = FlowNature.PresentType.equals(flowModel.getRejectType());
        taskNode.setNodeUp(flowModel.getRejectStep());
        //驳回记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.reject.getCode()).flowModel(flowModel).userId(userId).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskUtil.createRecord(operatorRecord);
        //修改或签、会签经办数据
        TaskHandleIdStatus handleIdStatus = new TaskHandleIdStatus();
        handleIdStatus.setStatus(0);
        handleIdStatus.setNodeModel(nodeModel);
        handleIdStatus.setUserInfo(userInfo);
        handleIdStatus.setTaskNodeList(taskNodeList);
        flowTaskUtil.handleIdStatus(operator, handleIdStatus);
        //更新流当前程经办状态
        flowTaskOperatorService.update(operator);
        //判断是否是会签
        List<FlowTaskOperatorEntity> rejectOperatorList = flowTaskOperatorService.getList(taskNode.getTaskId()).stream().filter(t -> t.getTaskNodeId().equals(taskNode.getId()) && FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        FlowCountersignModel countersign = new FlowCountersignModel();
        countersign.setTaskNode(taskNode);
        countersign.setOperatorList(rejectOperatorList);
        boolean isReject = flowTaskUtil.isRejectCountersign(countersign);
        //更新驳回节点
        //todo 123456789
        FlowUpModel flowUpModel = FlowUpModel.builder().flowTask(flowTask).taskNode(taskNode).taskNodeList(taskNodeList)
                .isReject(isReject).rejectType(!rejectType).flowModel(flowModel).isAudit(false).build();
        List<FlowTaskNodeEntity> upAll = flowTaskUtil.flowUp(flowUpModel);
        boolean isStart = upAll.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).count() > 0;
        List<ChildNodeList> nextOperatorList = new ArrayList<>();
        for (FlowTaskNodeEntity entity : upAll) {
            ChildNodeList node = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
            nextOperatorList.add(node);
        }
        //驳回节点
        List<FlowTaskOperatorEntity> operatorList = new ArrayList<>();
        if (!isStart) {
            //赋值数据
            flowModel.setProcessId(flowTask.getId());
            flowModel.setId(flowTask.getId());
            Map<String, Object> data = serviceUtil.infoData(taskNode.getFormId(), taskNode.getTaskId());
            flowModel.setFormData(data);
            FlowOperator flowOperator = FlowOperator.builder().operatorListAll(operatorList).flowModel(flowModel).flowTask(flowTask).nodeList(nextOperatorList).taskNodeListAll(taskNodeList).reject(true).asyncTaskList(new HashMap<>()).build();
            flowTaskUtil.nextOperator(flowOperator);
        }
        //保存冻结的数据
        if (rejectType && isReject) {
            String operatorJson = JsonUtil.getObjectToString(JsonUtil.getJsonToList(operatorEntityList, FlowTaskOperatorRejectModel.class));
            FlowRejectDataEntity rejectEntity = new FlowRejectDataEntity();
            rejectEntity.setTaskNodeJson(taskNodeJson);
            rejectEntity.setTaskOperatorJson(operatorJson);
            rejectEntity.setTaskJson(taskJson);
            rejectEntity.setId(flowTask.getId());
            flowTask.setRejectId(flowTask.getId());
            flowRejectDataService.createOrUpdate(rejectEntity);
        }
        //更新流程节点
        flowTask.setTaskNodeId(null);
        flowTaskService.update(flowTask);
        //显示当前的驳回记录
        flowTaskOperatorRecordService.update(operatorRecord.getId(), operatorRecord);
        for (FlowTaskOperatorEntity operatorEntity : operatorList) {
            operatorEntity.setReject(rejectType ? "1" : "");
        }
        //创建审批人
        Map<String, List<FlowTaskOperatorEntity>> operatorMap = operatorList.stream().collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId));
        for (ChildNodeList childNodeList : nextOperatorList) {
            Properties properties = childNodeList.getProperties();
            boolean counterSign = FlowNature.ImproperApprover.equals(properties.getCounterSign());
            if (counterSign && StringUtil.isEmpty(flowModel.getFreeApproverUserId())) {
                List<FlowTaskOperatorEntity> listAll = operatorMap.get(childNodeList.getTaskNodeId()) != null ? operatorMap.get(childNodeList.getTaskNodeId()) : new ArrayList<>();
                flowOperatorUserService.create(JsonUtil.getJsonToList(listAll, FlowOperatorUserEntity.class));
            }
        }
        //过滤依次审批人
        flowTaskUtil.improperApproverUser(operatorList, taskNodeList, nodeModel, operator);
        flowTaskOperatorService.create(operatorList);
        //更新节点接收时间
        flowTaskUtil.taskCreatTime(operatorList);
        //获取抄送人
        List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();
        flowTaskUtil.circulateList(nodeModel, taskNodeList, circulateList, flowModel, flowTask);
        flowTaskCirculateService.create(circulateList);
        //节点事件
        flowMsgUtil.event(5, nodeModel, operatorRecord, flowModel);
        List<FlowParameterModel> parameterModels = FlowContextHolder.getAllEvent();
        if (parameterModels.size() == 0) {
            //发送消息
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            flowMsgModel.setCirculateList(circulateList);
            flowMsgModel.setNodeList(taskNodeList);
            flowMsgModel.setOperatorList(operatorList);
            flowMsgModel.setReject(true);
            flowMsgModel.setCopy(true);
            flowMsgModel.setWait(isStart ? false : true);
            flowMsgModel.setStart(isStart);
            flowMsgModel.setData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
            flowMsgModel.setTaskNodeEntity(taskNode);
            flowMsgModel.setTaskEntity(flowTask);
            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
            FlowTaskOperatorRecordEntity taskOperatorRecord = new FlowTaskOperatorRecordEntity();
            taskOperatorRecord.setHandleId(userInfo.getUserId());
            flowMsgModel.setFlowModel(flowModel);
            flowMsgUtil.message(flowMsgModel);
            //超时
            insTimeOutRedis(flowModel, operatorList, userInfo, flowTask, taskNodeList);
            //自动审批
            FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorList).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).build();
            flowTaskUtil.approve(approveModel);
        }*/
    }

    @Override
    public void rejectAll(FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, FlowModel flowModel) throws WorkFlowException {
        String rejectStep = flowModel.getRejectStep();
        Integer rejectType = flowModel.getRejectType();
        String taskNodeId = operator.getTaskNodeId();
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(taskNodeId).includeProcessVariables().singleResult();
        Map<String, Object> processVariables = task.getProcessVariables();
        String templateJsonId = MapUtil.getStr(processVariables, FLOW_TEMPLATE_JSON_ID);
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(templateJsonId);

        List<FlowTaskCirculateEntity> flowTaskCirculateEntities =new ArrayList<>();
        String copyIds = flowModel.getCopyIds();
        String applyUserId = MapUtil.getStr(processVariables, APPLY_USER_ID);
        UserEntity userServiceInfo = userService.getInfo(applyUserId);
        if(StringUtils.isNotBlank(copyIds)){
            String[] split = copyIds.split(",");
            List<String> arr = Arrays.asList(split);
            for (String s : arr) {
                FlowTaskCirculateEntity circulate = new FlowTaskCirculateEntity();
                circulate.setId(RandomUtil.uuId());
                circulate.setObjectId(s);
                circulate.setNodeCode(task.getTaskDefinitionKey());
                circulate.setNodeName(task.getName());
//                        circulate.setTaskNodeId(taskId);
                circulate.setTaskId(task.getProcessInstanceId());
                circulate.setEnCode(MapUtil.getStr(processVariables,BILL_CODE));
                circulate.setFullName(MapUtil.getStr(processVariables,BUSINESS_TITLE));
                circulate.setTemplateId(MapUtil.getStr(processVariables,FLOW_ENGINE_ID));
                circulate.setFlowId(MapUtil.getStr(processVariables,FLOW_TEMPLATE_JSON_ID));
                circulate.setFlowCategory(MapUtil.getStr(processVariables,PROCESS_CATEGORY));
                circulate.setFlowUrgent(MapUtil.getInt(processVariables,FLOW_URGENT));
                circulate.setCreatorTime(new Date());
                circulate.setApplyUserId(userServiceInfo.getRealName()+"/"+userServiceInfo.getAccount());
                circulate.setApplyUserIdReal(userServiceInfo.getId());
                circulate.setTaskNodeId(task.getId());
                circulate.setProcessStatus(MapUtil.getInt(processVariables,PROCESS_STATUS));
                flowTaskCirculateEntities.add(circulate);
            }
            flowTaskCirculateService.create(flowTaskCirculateEntities);

        }
        taskService.setPriority(task.getId(),51);
        //更新审批意见
        //1.1更新审批记录表
        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> flowTaskOperatorRecordEntityLambdaQueryWrapper= new LambdaQueryWrapper<>();
        flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
        flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getHandleId,userProvider.get().getUserId());
//            flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getOperatorId,operator.getId());
        FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(flowTaskOperatorRecordEntityLambdaQueryWrapper);
        flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
        flowTaskOperatorRecordEntity.setHandleTime(new Date());
        flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
        flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
        flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);




        //
        Map<String,Object> variablesMap = new HashMap<>();
        variablesMap.put(PROCESS_STATUS,FlowTaskStatusEnum.Reject.getCode());
        runtimeService.setVariables(task.getProcessInstanceId(),variablesMap);
        String formKey = task.getFormKey();
        String[] split = formKey.split(taskDescriptionSeparator);
        Map<String, Object> map = flowTaskUtil.infoData(split[0], split[1]);
        //Bug: 表单数据 set进去  因为  JNPF 官方点击拒绝的时候不会传递 表单数据字段
//        flowModel.setFormData(map);
        //1.2调用事件
        Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
        String property = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, task.getTaskDefinitionKey(), "userTask");
        Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
        });
        //事件调用
        FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
        flowTaskOperatorRecordDTO.setAssignee(task.getAssignee());
        flowTaskOperatorRecordDTO.setProcessInstanceId(task.getProcessInstanceId());
        flowTaskOperatorRecordDTO.setTaskId(task.getId());
        flowMsgUtil.event(5, properties, flowTaskOperatorRecordDTO, flowModel, bpmnModelMainProcess, flowModel.getRejectStep());
        //1.3调用通知
        Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
        MsgConfig rejectMsgConfig = properties.getRejectMsgConfig();
        Integer msgConfigOnn = rejectMsgConfig.getOn();

        Boolean messageFlag=false;
        if(msgConfigOnn!=0){
            if(msgConfigOnn==2){
                if(firstNodeProperty.getRejectMsgConfig().getOn()!=0){
                    messageFlag=true;
                }
            }
            else{
                messageFlag=true;
            }
        }

        if(messageFlag){
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            if(CollUtil.isNotEmpty(flowTaskCirculateEntities)){
                flowMsgModel.setCirculateList(flowTaskCirculateEntities);
                flowMsgModel.setCopy(Boolean.TRUE);
            }
            flowMsgModel.setStartNodeProperties(firstNodeProperty);
            flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
            flowMsgModel.setWait(Boolean.FALSE);
            flowMsgModel.setReject(Boolean.TRUE);
            List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
            operatorEntityList.add(operator);
            flowMsgModel.setOperatorList(operatorEntityList);
            flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
            FlowTaskDTO flowTaskDTO = new FlowTaskDTO();

            flowTaskDTO.setCreatorUserId(MapUtil.getStr(processVariables,APPLY_USER_ID));
            flowTaskDTO.setStatus(MapUtil.getInt(processVariables,PROCESS_STATUS));
            flowTaskDTO.setFullName(MapUtil.getStr(processVariables,BUSINESS_TITLE));
            flowMsgModel.setTaskEntity(flowTaskDTO);

            FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
            flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
            flowTaskNodeDTO.setTaskNodeId(task.getId());
            flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);
            flowMsgModel.setFlowModel(flowModel);
            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
            flowMsgModel.setTaskId(task.getProcessInstanceId());
            flowMsgModel.setTaskNodeId(task.getId());
            flowMsgUtil.message(flowMsgModel);
        }


        String rejectStepConfig = properties.getRejectStep();

        List<String> activeActivityIds = runtimeService.getActiveActivityIds(task.getProcessInstanceId());
            ArrayList<String> distinct = CollUtil.distinct(activeActivityIds);

            if(FlowNature.START.equals(rejectStepConfig)){

                LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                otherLabmdaWrapper.in(FlowTaskOperatorRecordEntity::getNodeCode,distinct);
                otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                    taskOperatorRecordEntity.setHandleTime(new Date());
                    taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                }
                flowTaskOperatorRecordService.updateBatchById(list);

                if(RejectTypeEnum.CURRENT_NODE.getCode().equals(rejectType)){
                    runtimeService.setVariable(task.getProcessInstanceId(),REJECT_NODE,CollUtil.join(distinct,","));
                }

                List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                runtimeService.createChangeActivityStateBuilder()
                        .processInstanceId(task.getProcessInstanceId())
                        .moveExecutionsToSingleActivityId(mainExecutions,rejectStep)
                        .changeState();
            }
            //只有重新审批才有
            else if(FlowNature.UP.equals(rejectStepConfig)){
                List<String> rejectList = Arrays.asList(rejectStep.split(","));
                if(rejectList.size()>1) {
                    if (distinct.size() > 1) {
                        throw new WorkFlowException("不支持多对多审批链路跳转,需要修改节点基础设置!!");
                    }
                    else{

                        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                        otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getNodeCode,task.getTaskDefinitionKey());
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                        List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                        for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                            taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                            taskOperatorRecordEntity.setHandleTime(new Date());
                        }
                        flowTaskOperatorRecordService.updateBatchById(list);
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(task.getProcessInstanceId())
                                .moveSingleActivityIdToActivityIds(task.getTaskDefinitionKey(),rejectList)
                                .changeState();
                    }
                }
                else{
                    LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                    otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                    otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                    otherLabmdaWrapper.in(FlowTaskOperatorRecordEntity::getNodeCode,distinct);
                    otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                    List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                    for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                        taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                        taskOperatorRecordEntity.setHandleTime(new Date());
                    }
                    flowTaskOperatorRecordService.updateBatchById(list);
                    List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                    runtimeService.createChangeActivityStateBuilder()
                            .processInstanceId(task.getProcessInstanceId())
                            .moveExecutionsToSingleActivityId(mainExecutions,rejectList.get(0))
                            .changeState();
                }
            }
            else if(FlowNature.Reject.equals(rejectStepConfig)){
                String rejectTaskProperty = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, rejectStep, "userTask");
                Properties rejectProperties = JSONObject.parseObject(rejectTaskProperty, new TypeReference<Properties>() {
                });
                String targetBranchFlowId = rejectProperties.getBranchFlowId();
                String branchFlowId = properties.getBranchFlowId();

                if(StringUtils.isNotBlank(branchFlowId)){
                    if(branchFlowId.equals(targetBranchFlowId)){
                        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                        otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getNodeCode,task.getTaskDefinitionKey());
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                        List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                        for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                            taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                            taskOperatorRecordEntity.setHandleTime(new Date());
                        }
                        flowTaskOperatorRecordService.updateBatchById(list);

                        if(RejectTypeEnum.CURRENT_NODE.getCode().equals(rejectType)){
                            runtimeService.setVariable(task.getProcessInstanceId(),REJECT_NODE,task.getTaskDefinitionKey());
                        }

                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(task.getProcessInstanceId())
                                .moveActivityIdTo(task.getTaskDefinitionKey(),rejectStep)
                                .changeState();
                    }
                    else{
                        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                        otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                        otherLabmdaWrapper.in(FlowTaskOperatorRecordEntity::getNodeCode,distinct);
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                        List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                        for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                            taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                            taskOperatorRecordEntity.setHandleTime(new Date());
                        }
                        flowTaskOperatorRecordService.updateBatchById(list);
                        if(RejectTypeEnum.CURRENT_NODE.getCode().equals(rejectType)){
                            runtimeService.setVariable(task.getProcessInstanceId(),REJECT_NODE,CollUtil.join(distinct,","));
                        }
                        List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(task.getProcessInstanceId())
                                .moveExecutionsToSingleActivityId(mainExecutions,rejectStep)
                                .changeState();
                    }
                }
                else{

                    LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                    otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                    otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                    otherLabmdaWrapper.in(FlowTaskOperatorRecordEntity::getNodeCode,distinct);
                    otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                    List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                    for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                        taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                        taskOperatorRecordEntity.setHandleTime(new Date());
                    }
                    flowTaskOperatorRecordService.updateBatchById(list);
                    if(RejectTypeEnum.CURRENT_NODE.getCode().equals(rejectType)){
                        runtimeService.setVariable(task.getProcessInstanceId(),REJECT_NODE,CollUtil.join(distinct,","));
                    }
                    List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                    runtimeService.createChangeActivityStateBuilder()
                            .processInstanceId(task.getProcessInstanceId())
                            .moveExecutionsToSingleActivityId(mainExecutions,rejectStep)
                            .changeState();
                }
            }
            else{
                String rejectTaskProperty = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, rejectStep, "userTask");
                Properties rejectProperties = JSONObject.parseObject(rejectTaskProperty, new TypeReference<Properties>() {
                });
                String targetBranchFlowId = rejectProperties.getBranchFlowId();
                String branchFlowId = properties.getBranchFlowId();

                if(StringUtils.isNotBlank(branchFlowId)){
                    if(branchFlowId.equals(targetBranchFlowId)){

                        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                        otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getNodeCode,task.getTaskDefinitionKey());
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                        List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                        for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                            taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                            taskOperatorRecordEntity.setHandleTime(new Date());
                        }
                        flowTaskOperatorRecordService.updateBatchById(list);

                        if(RejectTypeEnum.CURRENT_NODE.getCode().equals(rejectType)){
                            runtimeService.setVariable(task.getProcessInstanceId(),REJECT_NODE,task.getTaskDefinitionKey());
                        }
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(task.getProcessInstanceId())
                                .moveActivityIdTo(task.getTaskDefinitionKey(),rejectStep)
                                .changeState();
                    }
                    else{
                        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                        otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                        otherLabmdaWrapper.in(FlowTaskOperatorRecordEntity::getNodeCode,distinct);
                        otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                        List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                        for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                            taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                            taskOperatorRecordEntity.setHandleTime(new Date());
                        }
                        flowTaskOperatorRecordService.updateBatchById(list);

                        if(RejectTypeEnum.CURRENT_NODE.getCode().equals(rejectType)){
                            runtimeService.setVariable(task.getProcessInstanceId(),REJECT_NODE,CollUtil.join(distinct,","));
                        }

                        List<String> executionsList = getMainExecutions(task.getProcessInstanceId());
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(task.getProcessInstanceId())
                                .moveExecutionsToSingleActivityId(executionsList,rejectStep)
                                .changeState();
//                            runtimeService.createChangeActivityStateBuilder()
//                                    .processInstanceId(task.getProcessInstanceId())
//                                    .moveActivityIdsToSingleActivityId(distinct,rejectStep)
//                                    .changeState();
                    }
                }
                else{
                    LambdaQueryWrapper<FlowTaskOperatorRecordEntity> otherLabmdaWrapper= new LambdaQueryWrapper<>();
                    otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,task.getProcessInstanceId());
                    otherLabmdaWrapper.ne(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                    otherLabmdaWrapper.in(FlowTaskOperatorRecordEntity::getNodeCode,distinct);
                    otherLabmdaWrapper.eq(FlowTaskOperatorRecordEntity::getHandleStatus,FlowRecordEnum.DOING.getCode());
                    List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(otherLabmdaWrapper);
                    for (FlowTaskOperatorRecordEntity taskOperatorRecordEntity : list) {
                        taskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                        taskOperatorRecordEntity.setHandleTime(new Date());
                    }
                    flowTaskOperatorRecordService.updateBatchById(list);

                    if(RejectTypeEnum.CURRENT_NODE.getCode().equals(rejectType)){
                        runtimeService.setVariable(task.getProcessInstanceId(),REJECT_NODE,CollUtil.join(distinct,","));
                    }

                    List<String> mainExecutions = getMainExecutions(task.getProcessInstanceId());
                    runtimeService.createChangeActivityStateBuilder()
                            .processInstanceId(task.getProcessInstanceId())
                            .moveExecutionsToSingleActivityId(mainExecutions,rejectStep)
                            .changeState();
                }
            }






    }

    @Override
    @DSTransactional
    public void reject(FlowModel flowModel) throws WorkFlowException {
        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,flowModel.getId());
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        //验证当前节点是否被锁定
        activitiUtils.validProcessStatus(operator.getTaskId());
        flowModel.setUserInfo(userInfo);
        FlowTaskEntity flowTask = new FlowTaskEntity();
        //调用驳回操作
        rejectAll(flowTask, operator, flowModel);
    }

    @Override
    @DSTransactional
    public void recall(String id, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(id).includeProcessVariables().singleResult();
        if (historicTaskInstance == null) {
            throw new WorkFlowException("流程已经结束,无法撤回");
        }
        //判断流程是否结束
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).includeProcessVariables().singleResult();
        if(processInstance==null){
            throw new WorkFlowException("流程已经结束,无法撤回");
        }
        activitiUtils.validProcessStatus(historicTaskInstance.getProcessInstanceId());

        List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstance.getProcessInstanceId());
        Process process = getBpmnModelMainProcess(processInstance.getProcessDefinitionId());
        String taskDefinitionKey = historicTaskInstance.getTaskDefinitionKey();
        if(activeActivityIds.contains(taskDefinitionKey)){
            throw new WorkFlowException("当前已经处于此节点,不需要撤回");
        }

        if(activeActivityIds==null || activeActivityIds.isEmpty()){
            throw new WorkFlowException("当前流程已经被挂起,无法撤回,请联系管理员重试");
        }

        ArrayList<String> distinct = CollectionUtil.distinct(activeActivityIds);
        String currentNodeId="";

        currentNodeId = activeActivityIds.get(0);
        FlowElement flowElement = process.getFlowElement(currentNodeId);
        FlowNode currentNode = BpmnModelUtils.getFlowNodeById(process, currentNodeId);
        FlowNode flowNodeById = getFlowNodeById(process, taskDefinitionKey);
        List<SequenceFlow> outgoingFlows = flowNodeById.getOutgoingFlows();
        List<String> outGoingElements=new ArrayList<>();
        for (SequenceFlow outgoingFlow : outgoingFlows) {
            FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
            if(targetFlowElement instanceof ExclusiveGateway){
                List<SequenceFlow> outgoingFlows1 = ((ExclusiveGateway) targetFlowElement).getOutgoingFlows();
                for (SequenceFlow sequenceFlow : outgoingFlows1) {
                    outGoingElements.add(sequenceFlow.getTargetFlowElement().getId());
                }
            }
            else{
                outGoingElements.add(targetFlowElement.getId());
            }
        }
        Collection<String> intersection = CollectionUtil.intersection(outGoingElements, activeActivityIds);
        if(CollectionUtil.isEmpty(intersection)){
            throw new WorkFlowException("当前节点下一节点已经被办理,无法撤回!");
        }

        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        operatorRecord.setNodeCode(taskDefinitionKey);
        operatorRecord.setNodeName(historicTaskInstance.getName());
        operatorRecord.setHandleId(historicTaskInstance.getAssignee());
        operatorRecord.setReceiveTime(new Date());
        operatorRecord.setOperatorId(historicTaskInstance.getAssignee());
//        operatorRecord.setTaskOperatorId(operator.getId());
//        operatorRecord.setTaskNodeId(historicTaskInstance.getId());
        operatorRecord.setTaskId(historicTaskInstance.getProcessInstanceId());
        operatorRecord.setId(RandomUtil.uuId());
        operatorRecord.setHandleStatus(FlowRecordEnum.recall.getCode());
        operatorRecord.setHandleTime(new Date());
        operatorRecord.setHandleOpinion(flowModel.getHandleOpinion());
        operatorRecord.setSignImg(flowModel.getSignImg());
        operatorRecord.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        flowTaskOperatorRecordService.save(operatorRecord);

        String[] split = historicTaskInstance.getFormKey().split(taskDescriptionSeparator);
        Map<String, Object> result = flowTaskUtil.infoData(split[0], split[1]);
        flowModel.setFormData(result);


        String processInstanceId = historicTaskInstance.getProcessInstanceId();
        if(flowElement instanceof UserTask){
//            org.flowable.task.api.Task currentTask = activitiDataBaseUtils.getTaskByProcessInstanceIdAndTaskDefinitionKey(processInstanceId, currentNodeId);
//            taskService.setVariableLocal(currentTask.getId(),TASK_STATE,FlowRecordEnum.recall.getCode());
            List<String> mainExecutions = getMainExecutions(processInstanceId);
            runtimeService.createChangeActivityStateBuilder()
                    .processInstanceId(processInstanceId)
                    .moveExecutionsToSingleActivityId(mainExecutions,taskDefinitionKey)
                    .changeState();
            //1.2调用事件
            Process bpmnModelMainProcess = getBpmnModelMainProcess(historicTaskInstance.getProcessDefinitionId());
            String property = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, historicTaskInstance.getTaskDefinitionKey(), "userTask");
            Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
            });
            FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
            flowTaskOperatorRecordDTO.setAssignee(operatorRecord.getHandleId());
            flowTaskOperatorRecordDTO.setProcessInstanceId(operatorRecord.getTaskId());
            flowTaskOperatorRecordDTO.setTaskId(operatorRecord.getTaskNodeId());
            flowMsgUtil.event(6, properties, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,taskDefinitionKey);

        }
        else if(flowElement instanceof ReceiveTask){


            List<String> mainExecutions = getMainExecutions(processInstanceId);
            runtimeService.createChangeActivityStateBuilder()
                    .processInstanceId(processInstanceId)
                    .moveExecutionsToSingleActivityId(mainExecutions,taskDefinitionKey)
                    .changeState();

        }
        else if(flowElement instanceof CallActivity){
            List<String> mainExecutions = getMainExecutions(processInstanceId);
            runtimeService.createChangeActivityStateBuilder()
                    .processInstanceId(processInstanceId)
                    .moveExecutionsToSingleActivityId(mainExecutions,taskDefinitionKey)
                    .changeState();
        }


    }

    @Override
    @DSTransactional
    public void revoke(FlowTaskEntity flowTask, FlowModel flowModel, boolean isParentId) throws WorkFlowException {
        //判断流程是否处于挂起状态
        flowTaskUtil.isSuspend(flowTask);
        UserInfo userInfo = flowModel.getUserInfo();
        TaskNodeListModel nodeListModel = TaskNodeListModel.builder().id(flowTask.getId()).state(FlowNodeEnum.Process.getCode()).build();
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(nodeListModel,
                FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getNodePropertyJson, FlowTaskNodeEntity::getFormId,
                FlowTaskNodeEntity::getTaskId, FlowTaskNodeEntity::getNodeType, FlowTaskNodeEntity::getNodeCode
        );
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowTask.getFlowId());
        FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
        ChildNodeList childNode = JsonUtil.getJsonToBean(templateJson.getFlowTemplateJson(), ChildNodeList.class);
        childNode.setTaskId(flowTask.getId());
        FlowTaskNodeEntity startNode = taskNodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).findFirst().orElse(null);
        if (startNode != null) {
            childNode = JsonUtil.getJsonToBean(startNode.getNodePropertyJson(), ChildNodeList.class);
        }
        Properties properties = childNode.getProperties();
        boolean revokeRule = FlowNature.RevokeTerminate.equals(properties.getRevokeRule());
        Map<String, Object> objectMap = serviceUtil.infoData(properties.getFormId(), flowTask.getId());
        flowModel.setFormData(objectMap);
        //删除节点
        flowTaskNodeService.update(flowTask.getId());
        //删除经办
        flowTaskOperatorService.update(flowTask.getId());
        //删除候选人
        flowCandidatesService.deleteByTaskId(flowTask.getId());
        //删除发起用户信息
        flowUserService.deleteByTaskId(flowTask.getId());
        //更新当前节点
        flowTask.setThisStep("开始");
        flowTask.setCompletion(FlowNature.ProcessCompletion);
        flowTask.setStatus(revokeRule || !isParentId ? FlowTaskStatusEnum.Revoke.getCode() : FlowTaskStatusEnum.Resubmit.getCode());
        flowTaskService.update(flowTask);
        //撤回记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
        operator.setTaskId(childNode.getTaskId());
        operator.setTaskNodeId(childNode.getTaskNodeId());
        operator.setNodeName(properties.getTitle());
        operator.setNodeCode(properties.getNodeId());
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.revoke.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //撤回事件
        operatorRecord.setHandleStatus(FlowTaskStatusEnum.Revoke.getCode());
//        flowMsgUtil.event(3, childNode, operatorRecord, flowModel);
        List<FlowParameterModel> parameterModels = FlowContextHolder.getAllEvent();
        if (parameterModels.size() > 0) {
            FlowModel cancelModel = new FlowModel();
            cancelModel.setUserInfo(flowModel.getUserInfo());
            cancel(Collections.singletonList(flowTask.getId()), cancelModel);
        } else {
            List<String> childAllList = flowTaskService.getChildAllList(flowTask.getId());
            childAllList.remove(flowTask.getId());
            FlowModel cancelModel = new FlowModel();
            cancelModel.setUserInfo(flowModel.getUserInfo());
            revoke(childAllList, cancelModel, false);
        }
    }


    @Override
    @DSTransactional
    public void revoke(List<String> id, FlowModel flowModel, boolean isParentId) throws WorkFlowException {
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(id.get(0)).includeProcessVariables().singleResult();
//        List<String> activeActivityIds = runtimeService.getActiveActivityIds(historicProcessInstance.getId());
//        ArrayList<String> distinct = CollUtil.distinct(activeActivityIds);
//        String currentNode = activeActivityIds.get(0);
//        HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().processInstanceId(historicProcessInstance.getId())
//                .activityId(currentNode).unfinished().listPage(0, 1).get(0);
        UserTask firstUserTaskNode = getFirstUserTaskNode(historicProcessInstance.getProcessDefinitionId());
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(historicProcessInstance.getId()).taskDefinitionKey(firstUserTaskNode.getId()).listPage(0, 1);
        HistoricTaskInstance historicTaskInstance = historicTaskInstances.get(0);



        flowModel.setTaskNodeId(historicTaskInstance.getId());

        flowModel.setTaskId(historicProcessInstance.getId());
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        operatorRecord.setNodeCode(historicTaskInstance.getTaskDefinitionKey());
        operatorRecord.setNodeName(historicTaskInstance.getName());
        String userId = userProvider.get().getUserId();
        operatorRecord.setHandleId(userId);
        operatorRecord.setReceiveTime(new Date());
        operatorRecord.setOperatorId(userId);
//        operatorRecord.setTaskOperatorId(operator.getId());
        operatorRecord.setTaskNodeId(historicTaskInstance.getId());
        operatorRecord.setTaskId(historicTaskInstance.getProcessInstanceId());
        operatorRecord.setId(RandomUtil.uuId());
        operatorRecord.setHandleStatus(FlowRecordEnum.revoke.getCode());
        operatorRecord.setHandleTime(new Date());
        operatorRecord.setHandleOpinion(flowModel.getHandleOpinion());
        operatorRecord.setSignImg(flowModel.getSignImg());
        operatorRecord.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        flowTaskOperatorRecordService.save(operatorRecord);
        runtimeService.setVariable(historicProcessInstance.getId(),PROCESS_STATUS,FlowTaskStatusEnum.Revoke.getCode());
        UserTask firstNode = getFirstNode(getBpmnModelMainProcess(historicProcessInstance.getProcessDefinitionId()));

        //
        Properties firstNodeProperty = getFirstNodeProperty(historicProcessInstance.getProcessDefinitionId());
        List<String> activeActivityIds = runtimeService.getActiveActivityIds(flowModel.getTaskId());
        if(activeActivityIds.contains(firstNode.getId())){
            throw new WorkFlowException("当前已经在发起节点,不需要撤回!");
        }

        Integer revokeRule = firstNodeProperty.getRevokeRule();
        String formId=firstNodeProperty.getFormId();
        String businessKey = historicProcessInstance.getBusinessKey();
        Map<String, Object> firstNodeFormData = flowTaskUtil.infoData(formId,businessKey);
        flowModel.setFormData(firstNodeFormData);

        FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
        flowTaskOperatorRecordDTO.setAssignee(userId);
        flowTaskOperatorRecordDTO.setProcessInstanceId(historicTaskInstance.getProcessInstanceId());
        flowTaskOperatorRecordDTO.setTaskId(historicTaskInstance.getId());
        //开始事件
        Process bpmnModelMainProcess = getBpmnModelMainProcess(historicProcessInstance.getProcessDefinitionId());
        flowMsgUtil.event(3, firstNodeProperty, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,historicTaskInstance.getTaskDefinitionKey());
        //终止
        if(revokeRule.equals(1)){
            if(Boolean.TRUE.equals(firstNodeProperty.getHasCancelFlag())){
                runtimeService.deleteProcessInstance(historicProcessInstance.getId(),"流程撤回并终止");
                //开始事件
                flowMsgUtil.event(9, firstNodeProperty, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess,historicTaskInstance.getTaskDefinitionKey());
            }
            else{
                throw new WorkFlowException("该流程不允许撤销!,请去发起节点配置开启!");
            }
        }
        //撤回
        else{
            if(Boolean.TRUE.equals(firstNodeProperty.getHasRevokeFlag())){
                List<String> mainExecutions = getMainExecutions(flowModel.getTaskId());
                runtimeService.createChangeActivityStateBuilder()
                        .processInstanceId(flowModel.getTaskId())
                        .moveExecutionsToSingleActivityId(mainExecutions,firstNode.getId())
                        .changeState();
                Integer revokeDataRule = firstNodeProperty.getRevokeDataRule();
                //清空
                if(revokeDataRule.equals(2)){
                    //清空,清哪些表???  act_hi_actinst   暂时
                    String sql = "DELETE FROM ACT_HI_ACTINST where PROC_INST_ID_= ? AND END_TIME_ IS NOT NULL";
                    int update = jdbcTemplate.update(sql, flowModel.getTaskId());
                }
            }
            else{
                throw new WorkFlowException("该流程不允许撤回!,请去发起节点配置开启!");
            }
        }




    }


    private List<String> getMainExecutions(String processInstanceId) {
        List<Execution> dbExecList = runtimeService.createExecutionQuery().parentId(processInstanceId).list();
        List<String> executionsList=new ArrayList<>();
        for (Execution execution : dbExecList) {
            executionsList.add(execution.getId());
        }
        return executionsList;
    }

    @Override
    @DSTransactional
    public void cancel(FlowTaskEntity flowTask, FlowModel flowModel) throws WorkFlowException {
 /*       //判断流程是否处于挂起状态
        flowTaskUtil.isSuspend(flowTask);
        UserInfo userInfo = flowModel.getUserInfo();
        //终止记录
        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
        operator.setTaskId(flowTask.getId());
        operator.setNodeCode(flowTask.getThisStepId());
        operator.setNodeName(flowTask.getThisStep());
        //审批数据赋值
        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.cancel.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).build();
        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
        flowTaskOperatorRecordService.create(operatorRecord);
        //更新实例
        flowTask.setStatus(FlowTaskStatusEnum.Cancel.getCode());
        flowTask.setEndTime(new Date());
        flowTaskService.update(flowTask);
        //发送消息
        TaskNodeListModel taskNodeListModel = TaskNodeListModel.builder().id(flowTask.getId()).state(FlowNodeEnum.Process.getCode()).build();
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(taskNodeListModel,
                FlowTaskNodeEntity::getNodeType, FlowTaskNodeEntity::getId,
                FlowTaskNodeEntity::getTaskId, FlowTaskNodeEntity::getNodeType,
                FlowTaskNodeEntity::getNodePropertyJson
        );
        FlowTaskNodeEntity start = taskNodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).findFirst().orElse(null);
        if (start != null) {
            FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowTask.getFlowId());
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            flowMsgModel.setEnd(true);
            flowMsgModel.setNodeList(taskNodeList);
            flowMsgModel.setTaskEntity(flowTask);
            flowMsgModel.setTaskNodeEntity(start);
            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
            ChildNode childNode = JsonUtil.getJsonToBean(templateAllModel.getTemplateJson().getFlowTemplateJson(), ChildNode.class);
            String formId = childNode.getProperties().getFormId();
            Map<String, Object> data = serviceUtil.infoData(formId, flowTask.getId());
            flowMsgModel.setData(data);
            flowMsgModel.setFlowModel(flowModel);
            flowMsgUtil.message(flowMsgModel);
            //递归查询子流程，并终止
            List<String> childAllList = flowTaskService.getChildAllList(flowTask.getId());
            childAllList.remove(flowTask.getId());
            FlowModel cancelModel = new FlowModel();
            cancelModel.setUserInfo(flowModel.getUserInfo());
            cancel(childAllList, cancelModel);
        }*/
    }

    @Override
    @DSTransactional
    public void cancel(List<String> idList, FlowModel flowModel) throws WorkFlowException {
        for (String id : idList) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(id).includeProcessVariables().singleResult();
            Process bpmnModelMainProcess = getBpmnModelMainProcess(historicProcessInstance.getProcessDefinitionId());
            String globalEx = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, "", "global");
            jnpf.engine.assembly.GlobalExPropertyDTO exPropertyDTO = JSONObject.parseObject(globalEx, new TypeReference<jnpf.engine.assembly.GlobalExPropertyDTO>() {
            });
            //放开功能流程不能终止
//            if (exPropertyDTO.getFlowType() == 1) {
//                throw new WorkFlowException("功能流程不能终止");
//            }

            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
//        runtimeService.setVariable(historicProcessInstance.getId(),PROCESS_STATUS,FlowTaskStatusEnum.Cancel.getCode());
            String templateJsonId = MapUtil.getStr(processVariables, FLOW_TEMPLATE_JSON_ID);
            FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(templateJsonId);
            UserTask firstUserTaskNode = getFirstUserTaskNode(historicProcessInstance.getProcessDefinitionId());
            Properties properties = getFirstNodeProperty(historicProcessInstance.getProcessDefinitionId());
            String formId=properties.getFormId();
            String businessKey = historicProcessInstance.getBusinessKey();
            Map<String, Object> firstNodeFormData = flowTaskUtil.infoData(formId,businessKey);
            flowModel.setFormData(firstNodeFormData);
            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(id).taskDefinitionKey(firstUserTaskNode.getId()).listPage(0, 1).get(0);


            LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,historicTaskInstance.getId());
            operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userProvider.get().getUserId());
            FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);

            LambdaQueryWrapper<FlowTaskOperatorRecordEntity> flowTaskOperatorRecordEntityLambdaQueryWrapper  =new LambdaQueryWrapper<>();
            flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId,historicTaskInstance.getId());
            flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getHandleId,userProvider.get().getUserId());
            FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(flowTaskOperatorRecordEntityLambdaQueryWrapper);

            UserInfo user = UserProvider.getUser();
            FlowTaskOperatorRecordEntity cancelFlowTaskOperatorRecordEntity=new FlowTaskOperatorRecordEntity();
            cancelFlowTaskOperatorRecordEntity.setNodeName("结束");
            cancelFlowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.cancel.getCode());
            cancelFlowTaskOperatorRecordEntity.setHandleId(user.getUserId());
            Date date = new Date();
            cancelFlowTaskOperatorRecordEntity.setReceiveTime(date);
            cancelFlowTaskOperatorRecordEntity.setHandleTime(date);
            cancelFlowTaskOperatorRecordEntity.setOperatorId(user.getUserId());
//        cancelFlowTaskOperatorRecordEntity.setTaskOperatorId();
//        cancelFlowTaskOperatorRecordEntity.setTaskNodeId();
            cancelFlowTaskOperatorRecordEntity.setTaskId(historicProcessInstance.getId());
            cancelFlowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
            cancelFlowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
            cancelFlowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
            flowTaskOperatorRecordService.create(cancelFlowTaskOperatorRecordEntity);


            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
            //1.2调用事件
            FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
            flowTaskOperatorRecordDTO.setAssignee(flowModel.getTrueAssignee());
            flowTaskOperatorRecordDTO.setProcessInstanceId(id);
            UserTask firstNode = getFirstNode(bpmnModelMainProcess);
            List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(id).taskDefinitionKey(firstNode.getId()).listPage(0, 1);
            flowTaskOperatorRecordDTO.setTaskId(historicTaskInstances.get(0).getId());
            flowMsgUtil.event(9, properties, flowTaskOperatorRecordDTO, flowModel,bpmnModelMainProcess, Strings.EMPTY);
            //1.3调用通知
            Properties firstNodeProperty = getFirstNodeProperty(historicProcessInstance.getProcessDefinitionId());



            if(processInstance.isSuspended()){
                throw new WorkFlowException("该流程已经被挂起,请去恢复流程!");
            }
            runtimeService.deleteProcessInstance(id,"流程删除");
        }





    }
    @Override
    @DSTransactional
    public void cancelEx(List<String> id, FlowModel flowModel) {

        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,id.get(0));
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        flowModel.setUserInfo(userInfo);

        activitiUtils.validProcessStatus(operator.getTaskId());
        //
        String taskNodeId = operator.getTaskNodeId();
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(taskNodeId).singleResult();
        String executionId = managementService.executeCommand(new GetSecondExecutionIdCmd(task.getExecutionId()));
        Map<String, Object> variables = runtimeService.getVariables(executionId);
        Integer rejectNum = MapUtil.getInt(variables, RootExecutionVariableConstants.MULTI_INSTANCE_NUM_REJECT);
        if(rejectNum==null){
            runtimeService.setVariable(executionId,RootExecutionVariableConstants.MULTI_INSTANCE_NUM_REJECT,1);
        }
        else{
            rejectNum=rejectNum+1;
            runtimeService.setVariable(executionId,RootExecutionVariableConstants.MULTI_INSTANCE_NUM_REJECT,rejectNum);
        }

        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,operator.getId());
        FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
        flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.Disagree.getCode());
        flowTaskOperatorRecordEntity.setHandleTime(new Date());
        flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
        flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
        flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);

        taskService.complete(task.getId());


    }
    @Override
    @DSTransactional
    public void assign(String id, FlowModel flowModel) throws WorkFlowException {



        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();

        String freeApproverUserId = flowModel.getFreeApproverUserId();
        String nodeCode = flowModel.getNodeCode();

//        Map<String, String> nodeUser = FlowContextHolder.getNodeUser();
//        nodeUser.put(nodeCode,freeApproverUserId);
        FlowContextHolder.addNodeUser(nodeCode,freeApproverUserId);
        List<String> activeActivityIds = runtimeService.getActiveActivityIds(historicProcessInstance.getId());
        ArrayList<String> distinct = CollUtil.distinct(activeActivityIds);

        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
        operatorRecord.setId(RandomUtil.uuId());
        operatorRecord.setHandleStatus(FlowRecordEnum.assign.getCode());
        operatorRecord.setHandleTime(new Date());
        operatorRecord.setHandleOpinion(flowModel.getHandleOpinion());
        operatorRecord.setSignImg(flowModel.getSignImg());
        operatorRecord.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        operatorRecord.setHandleId(flowModel.getUserInfo().getUserId());
        operatorRecord.setReceiveTime(new Date());
        operatorRecord.setOperatorId(flowModel.getUserInfo().getUserId());
        operatorRecord.setTaskId(historicProcessInstance.getId());

        if(distinct.contains(nodeCode)){
            throw new WorkFlowException("不允许指派到正在激活的节点");

        }
        else{
            String currentNode = activeActivityIds.get(0);
            HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().processInstanceId(historicProcessInstance.getId())
                    .activityId(currentNode).unfinished().listPage(0, 1).get(0);
            operatorRecord.setNodeCode(historicActivityInstance.getActivityId());
            operatorRecord.setNodeName(historicActivityInstance.getActivityName());
//        operatorRecord.setTaskOperatorId(operator.getId());
//        operatorRecord.setTaskNodeId(historicTaskInstance.getId());
            operatorRecord.setTaskId(historicActivityInstance.getProcessInstanceId());
            flowTaskOperatorRecordService.save(operatorRecord);
            List<String> mainExecutions = getMainExecutions(historicProcessInstance.getId());
            runtimeService.createChangeActivityStateBuilder()
                    .processInstanceId(flowModel.getTaskId())
                    .moveExecutionsToSingleActivityId(mainExecutions,nodeCode)
                    .changeState();
        }
    }

    @Override
    public void transfer(FlowTaskOperatorEntity taskOperator, FlowModel flowModel) throws WorkFlowException {
//        flowTaskOperatorService.update(taskOperator);
//        TaskNodeListModel taskNodeListModel = TaskNodeListModel.builder().id(taskOperator.getTaskId()).state(FlowNodeEnum.Process.getCode()).build();
//        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(taskNodeListModel,
//                FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getNodePropertyJson, FlowTaskNodeEntity::getNodeCode,
//                FlowTaskNodeEntity::getNodeNext, FlowTaskNodeEntity::getTaskId, FlowTaskNodeEntity::getNodeType
//        );
//        FlowTaskNodeEntity taskNode = taskNodeList.stream().filter(t -> t.getId().equals(taskOperator.getTaskNodeId())).findFirst().orElse(null);
//        ChildNodeList childNode = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
//        FlowTaskEntity flowTask = flowTaskService.getInfoSubmit(taskNode.getTaskId(), FlowTaskEntity::getId, FlowTaskEntity::getFlowId, FlowTaskEntity::getFullName, FlowTaskEntity::getCreatorUserId, FlowTaskEntity::getStatus, FlowTaskEntity::getFlowFormContentJson);
//        //判断流程是否处于挂起状态
//        flowTaskUtil.isSuspend(flowTask);
//        //转办记录
//        UserInfo userInfo = flowModel.getUserInfo();
//        FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
//        FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
//        operator.setTaskId(taskOperator.getTaskId());
//        operator.setNodeCode(taskOperator.getNodeCode());
//        operator.setTaskNodeId(taskOperator.getTaskNodeId());
//        operator.setNodeName(taskOperator.getNodeName());
//        //审批数据赋值
//        FlowOperatordModel flowOperatordModel = FlowOperatordModel.builder().status(FlowRecordEnum.transfer.getCode()).flowModel(flowModel).userId(userInfo.getUserId()).operator(operator).operatorId(taskOperator.getHandleId()).build();
//        flowTaskUtil.operatorRecord(operatorRecord, flowOperatordModel);
//        flowTaskOperatorRecordService.create(operatorRecord);
//        //自动审批
//        List<FlowTaskOperatorEntity> operatorListAll = new ArrayList<>();
//        List<UserEntity> userName = new ArrayList() {{
//            UserEntity user = new UserEntity();
//            user.setId(taskOperator.getHandleId());
//            add(user);
//        }};
//        TaskOperatoUser taskOperatoUser = new TaskOperatoUser();
//        taskOperatoUser.setDate(new Date());
//        taskOperatoUser.setId(FlowNature.ParentId);
//        taskOperatoUser.setHandLeId(operator.getHandleId());
//        taskOperatoUser.setChildNode(childNode);
//        FlowAgreeRuleModel ruleModel = FlowAgreeRuleModel.builder().operatorListAll(operatorListAll).taskOperatoUser(taskOperatoUser).flowTask(flowTask).userName(userName).childNode(childNode).taskNodeList(taskNodeList).reject(false).build();
//        flowTaskUtil.flowAgreeRule(ruleModel);
//        operatorListAll.stream().forEach(t -> t.setId(taskOperator.getId()));
//        //发送消息
//        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowTask.getFlowId());
//        List<FlowTaskOperatorEntity> operatorList = new ArrayList() {{
//            FlowTaskOperatorEntity operatorEntity = new FlowTaskOperatorEntity();
//            operatorEntity.setId(taskOperator.getId());
//            operatorEntity.setTaskId(operatorRecord.getTaskId());
//            operatorEntity.setHandleId(taskOperator.getHandleId());
//            operatorEntity.setTaskNodeId(operatorRecord.getTaskNodeId());
//            add(operatorEntity);
//        }};
//        FlowMsgModel flowMsgModel = new FlowMsgModel();
//        flowMsgModel.setNodeList(taskNodeList);
//        flowMsgModel.setOperatorList(operatorList);
//        flowMsgModel.setData(JsonUtil.stringToMap(flowTask.getFlowFormContentJson()));
//        flowMsgModel.setTaskNodeEntity(taskNode);
//        flowMsgModel.setTaskEntity(flowTask);
//        flowMsgModel.setFlowTemplateAllModel(templateAllModel);
//        flowMsgModel.setFlowModel(flowModel);
//        flowMsgUtil.message(flowMsgModel);
//        //自动审批
//        FlowApproveModel approveModel = FlowApproveModel.builder().operatorList(operatorListAll).taskNodeList(taskNodeList).flowTask(flowTask).flowModel(flowModel).build();
//        flowTaskUtil.approve(approveModel);
//        //超时
//        insTimeOutRedis(flowModel, operatorListAll, userInfo, flowTask, taskNodeList);
    }

    @Override
    @DSTransactional
    public void transfer(FlowModel flowModel) throws WorkFlowException {
        String id = flowModel.getId();
        flowModel.setUserInfo(userProvider.get());

        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,id);
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity nativeOperator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        activitiUtils.validProcessStatus(nativeOperator.getTaskId());
        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,nativeOperator.getId());
        FlowTaskOperatorRecordEntity operatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);

        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(nativeOperator.getTaskNodeId()).includeProcessVariables().singleResult();
        taskService.setAssignee(task.getId(),flowModel.getFreeApproverUserId());
        Map<String, Object> processVariables = task.getProcessVariables();
        String templateJsonId = MapUtil.getStr(processVariables, FLOW_TEMPLATE_JSON_ID);
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(templateJsonId);
        Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
        UserTask userTask = (UserTask) bpmnModelMainProcess.getFlowElement(task.getTaskDefinitionKey());





        //先判断B这个人 有没有 operrator  如果有 用之前的 ,如果没有 新增

        operatorEntityLambdaQueryWrapper.clear();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,id);
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,flowModel.getFreeApproverUserId());
        FlowTaskOperatorEntity transfterOperator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);

        //更新源的转办意见
        operatorRecordEntity.setHandleStatus(FlowRecordEnum.transfer.getCode());
        operatorRecordEntity.setHandleTime(new Date());
        operatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
        flowTaskOperatorRecordService.updateById(operatorRecordEntity);

        //
        if(transfterOperator==null){
            transfterOperator = new FlowTaskOperatorEntity();
            transfterOperator.setId(RandomUtil.uuId());
            transfterOperator.setHandleId(flowModel.getFreeApproverUserId());
            transfterOperator.setTaskNodeId(task.getId());
            transfterOperator.setTaskId(task.getProcessInstanceId());
            transfterOperator.setNodeCode(task.getTaskDefinitionKey());
            transfterOperator.setNodeName(task.getName());
            transfterOperator.setDescription(task.getDescription());
            transfterOperator.setCreatorTime(new Date());
            transfterOperator.setCompletion(FlowNature.ProcessCompletion);
            transfterOperator.setState(FlowNodeEnum.Process.getCode());
            flowTaskOperatorService.save(transfterOperator);

            FlowTaskOperatorRecordEntity transferFlowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
            transferFlowTaskOperatorRecordEntity.setNodeCode(task.getTaskDefinitionKey());
            transferFlowTaskOperatorRecordEntity.setNodeName(task.getName());
            transferFlowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.DOING.getCode());
            transferFlowTaskOperatorRecordEntity.setHandleId(flowModel.getFreeApproverUserId());
            Date date = new Date();
            transferFlowTaskOperatorRecordEntity.setReceiveTime(date);
            transferFlowTaskOperatorRecordEntity.setHandleTime(date);
            transferFlowTaskOperatorRecordEntity.setOperatorId(flowModel.getFreeApproverUserId());
            transferFlowTaskOperatorRecordEntity.setTaskOperatorId(transfterOperator.getId());
            transferFlowTaskOperatorRecordEntity.setTaskNodeId(task.getId());
            transferFlowTaskOperatorRecordEntity.setTaskId(task.getProcessInstanceId());
            transferFlowTaskOperatorRecordEntity.setId(RandomUtil.uuId());
            flowTaskOperatorRecordService.create(transferFlowTaskOperatorRecordEntity);
        }
        else{

        }

        String property = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, task.getTaskDefinitionKey(), "userTask");
        Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
        });
        //1.3调用通知
        Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
        MsgConfig approveMsgConfig = properties.getWaitMsgConfig();
        Integer msgConfigOnn = approveMsgConfig.getOn();

        Boolean messageFlag=false;
        if(msgConfigOnn!=0){
            if(msgConfigOnn==2){
                if(firstNodeProperty.getWaitMsgConfig().getOn()!=0){
                    messageFlag=true;
                }
            }
            else{
                messageFlag=true;
            }
        }

        if(messageFlag){
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            flowMsgModel.setCopy(Boolean.FALSE);

            flowMsgModel.setStartNodeProperties(firstNodeProperty);
            flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
            List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
            operatorEntityList.add(transfterOperator);
            flowMsgModel.setOperatorList(operatorEntityList);
            flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
            FlowTaskDTO flowTaskDTO = new FlowTaskDTO();

            flowTaskDTO.setCreatorUserId(MapUtil.getStr(processVariables,APPLY_USER_ID));
            flowTaskDTO.setStatus(MapUtil.getInt(processVariables,PROCESS_STATUS));
            flowTaskDTO.setFullName(MapUtil.getStr(processVariables,BUSINESS_TITLE));
            flowMsgModel.setTaskEntity(flowTaskDTO);

            FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
            flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
            flowTaskNodeDTO.setTaskNodeId(task.getId());
            flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);
            flowMsgModel.setFlowModel(flowModel);
            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
            flowMsgModel.setTaskId(task.getProcessInstanceId());
            flowMsgModel.setTaskNodeId(task.getId());
            flowMsgUtil.message(flowMsgModel);
        }
    }


    @Override
    public FlowBeforeInfoVO getBeforeInfo(FlowModel flowModel) throws WorkFlowException {
        FlowBeforeInfoVO vo = new FlowBeforeInfoVO();
        String operatorId = flowModel.getTaskOperatorId();
        String flowId = flowModel.getFlowId();
        boolean parentId = FlowNature.ParentId.equals(flowModel.getId());
        String taskNodeId = flowModel.getTaskNodeId();
        String id = flowModel.getId();
        HistoricProcessInstance historicProcessInstance=null;
        if(StringUtils.isNotBlank(taskNodeId)){
            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskNodeId).singleResult();
            historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).includeProcessVariables().singleResult();
        }
        else{
            historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables().singleResult();
            if(historicProcessInstance==null){
                historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(id).includeProcessVariables().singleResult();
            }
        }
//        FlowTemplateAllModel templateAllModel =flowTaskUtil.templateJson(flowId);
//        FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
//        ChildNodeList childNodeAll = JsonUtil.getJsonToBean(templateJson.getFlowTemplateJson(), ChildNodeList.class);
//        String formId = childNodeAll.getProperties().getFormId();
        int num = 0;
        UserInfo userInfo = userProvider.get();
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowId);
        FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
        FlowTemplateEntity template = templateAllModel.getTemplate();
        Process bpmnModelMainProcess = getBpmnModelMainProcess(templateJson.getProcessDefinitionId());
        String globalEx = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, "", "global");
        GlobalExPropertyDTO globalExPropertyDTO = JSONObject.parseObject(globalEx, new TypeReference<GlobalExPropertyDTO>() {
        });
        Integer flowType = globalExPropertyDTO.getFlowType();
        UserTask destination = getFirstNode(bpmnModelMainProcess);
        Properties approversProperties = getFirstNodeProperty(templateJson.getProcessDefinitionId());
        vo.setApproversProperties(approversProperties);
        String formId = approversProperties.getFormId();
        vo.setFormOperates(approversProperties.getFormOperates());
        vo.setFormData(new HashMap<>());
        List<TaskNodeModel> unfinishList= new ArrayList<>();
        //流程已经发起
        if (historicProcessInstance != null) {
            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
            FlowTaskModel flowTaskModel = new FlowTaskModel();
            flowTaskModel.setId(historicProcessInstance.getId());
            flowTaskModel.setProcessId(historicProcessInstance.getId());
            flowTaskModel.setEnCode(MapUtil.getStr(processVariables,BILL_CODE));
            flowTaskModel.setFullName(MapUtil.getStr(processVariables,BUSINESS_TITLE));
            flowTaskModel.setFlowUrgent(MapUtil.getInt(processVariables,FLOW_URGENT));
            flowTaskModel.setFlowId(MapUtil.getStr(processVariables,FLOW_ENGINE_ID));
            flowTaskModel.setFlowCode(historicProcessInstance.getProcessDefinitionKey());
            flowTaskModel.setFlowName(templateJson.getFullName());
            flowTaskModel.setFlowType(template.getType());
            flowTaskModel.setFlowCategory(template.getCategory());
//            flowTaskModel.setFlowForm();
//            flowTaskModel.setFlowFormContentJson();
            flowTaskModel.setFlowTemplateJson(templateJson.getFlowTemplateJson());

            flowTaskModel.setFlowVersion(historicProcessInstance.getProcessDefinitionVersion()+"");
            flowTaskModel.setStartTime(historicProcessInstance.getStartTime().getTime());
            flowTaskModel.setStatus(MapUtil.getInt(processVariables,PROCESS_STATUS));
            Map<String, Object> infoData = flowTaskUtil.infoData(formId, historicProcessInstance.getBusinessKey());
            flowTaskModel.setFlowFormContentJson(JsonUtil.getObjectToString(infoData));
            if(historicProcessInstance.getEndTime()==null){
                flowTaskModel.setCompletion(50);
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(historicProcessInstance.getId()).singleResult();
                flowTaskModel.setSuspend(processInstance.isSuspended()?true:false);
                flowTaskModel.setEndTime(null);
            }
            else{
                flowTaskModel.setCompletion(100);
                flowTaskModel.setSuspend(false);
                flowTaskModel.setEndTime(historicProcessInstance.getEndTime().getTime());
            }
            flowTaskModel.setEnabledMark(1);
            flowTaskModel.setType(flowTaskModel.getFlowType());
            vo.setFlowTaskInfo(flowTaskModel);




            vo.setFormData(infoData);
            List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(historicProcessInstance.getId()).orderByHistoricActivityInstanceStartTime().asc().list();
            List<String> userIds= new ArrayList<>();//获取到流程现在所有的人的id
            Map<String,HistoricActivityInstance> historicActivityInstanceMap = new HashMap<>(); //list转map 只是userTask的
            for (HistoricActivityInstance historicActivityInstance : activityInstanceList) {
                if(StringUtils.isNotBlank(historicActivityInstance.getTaskId())){
                    historicActivityInstanceMap.put(historicActivityInstance.getTaskId(),historicActivityInstance);
                }
                if(StringUtils.isNotBlank(historicActivityInstance.getAssignee())){
                    userIds.add(historicActivityInstance.getAssignee());
                }
            }

            //已办人员
            List<FlowTaskOperatorRecordModel> recordList = new ArrayList<>();
            LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,historicProcessInstance.getId());
            lambdaQueryWrapper.orderByAsc(FlowTaskOperatorRecordEntity::getReceiveTime,FlowTaskOperatorRecordEntity::getHandleTime);
            List<FlowTaskOperatorRecordEntity> operatorRecordList = flowTaskOperatorRecordService.list(lambdaQueryWrapper);

            List<String>  taskNodeIds = new ArrayList<>();
            Map<String,String> flagMap = new HashMap<>();
            for (FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity : operatorRecordList) {
                userIds.add(flowTaskOperatorRecordEntity.getHandleId());
                taskNodeIds.add(flowTaskOperatorRecordEntity.getTaskNodeId());
            }
            if(CollUtil.isNotEmpty(taskNodeIds)){
                LambdaQueryWrapper<FlowEventLogEntity> flowEventLogEntityLambdaQueryWrapper= new LambdaQueryWrapper<>();
                flowEventLogEntityLambdaQueryWrapper.in(FlowEventLogEntity::getTaskNodeId,taskNodeIds);
                List<FlowEventLogEntity> list = flowEventLogService.list(flowEventLogEntityLambdaQueryWrapper);
                for (FlowEventLogEntity flowEventLogEntity : list) {
                    flagMap.put(flowEventLogEntity.getTaskNodeId(),"1");
                }
            }
            for (FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity : operatorRecordList) {
                if(StringUtils.isNotBlank(flowTaskOperatorRecordEntity.getTaskNodeId())){
                    String s = flagMap.get(flowTaskOperatorRecordEntity.getTaskNodeId());
                    if(StringUtils.isNotBlank(s)){
                        flowTaskOperatorRecordEntity.setIsLog(Boolean.TRUE);
                    }
                    else{
                        flowTaskOperatorRecordEntity.setIsLog(Boolean.FALSE);
                    }
                }
            }

            List<UserEntity> serviceUtilUserName = serviceUtil.getUserName(userIds);
            Map<String,List<HistoricActivityInstance>> map= new HashMap<>();
            for (HistoricActivityInstance historicActivityInstance : activityInstanceList) {
                List<HistoricActivityInstance> historicActivityInstances = map.get(historicActivityInstance.getActivityId());
                if(CollUtil.isEmpty(historicActivityInstances)){
                    historicActivityInstances=new LinkedList<>();
                    historicActivityInstances.add(historicActivityInstance);
                    map.put(historicActivityInstance.getActivityId(),historicActivityInstances);
                }
                else{
                    historicActivityInstances.add(historicActivityInstance);
                }
            }
            Collection<FlowElement> flowElements = bpmnModelMainProcess.getFlowElements();
            List<FlowElement> flowElementList = getFlowElementsWithOutSequenceFlow(bpmnModelMainProcess);
            List<FlowTaskNodeModel> flowTaskNodeListAll =new ArrayList<>();
            for (FlowElement flowElement : flowElementList) {
                FlowTaskNodeModel flowTaskNodeModel = new FlowTaskNodeModel();
                FlowNode flowNode=(FlowNode)flowElement;
                Object activityBehavior = flowNode.getBehavior();
                List<HistoricActivityInstance> activityInstances = map.get(flowNode.getId());
                Boolean flag =true;
                HistoricActivityInstance historicActivityInstance=null;
                //说明该节点还没有运行到
                if(CollUtil.isEmpty(activityInstances)){
                    flowTaskNodeModel.setCompletion(0);
                    flowTaskNodeModel.setType("2");
                    String documentation = flowNode.getDocumentation();
                    if(StringUtils.isBlank(documentation)){
                        flowTaskNodeModel.setUserName(flowNode.getName());
                    }
                    else{
                        String taskContent=documentation.split(taskDescriptionSeparator)[0];
                        flowTaskNodeModel.setUserName(taskContent);
                    }
                }
                else{
                    for (HistoricActivityInstance activityInstance : activityInstances) {
                        if(activityInstance.getEndTime()==null){
                            flag=false;
                            historicActivityInstance=activityInstance;
                            break;
                        }
                        else{
                            historicActivityInstance=activityInstance;
                        }
                    }
                    if(historicActivityInstance==null){
                        flowTaskNodeModel.setCompletion(0);
                        flowTaskNodeModel.setType("2");
                        String documentation = flowNode.getDocumentation();
                        if(StringUtils.isBlank(documentation)){
                            flowTaskNodeModel.setUserName(flowNode.getName());
                        }
                        else{
                            String taskContent=documentation.split(taskDescriptionSeparator)[0];
                            flowTaskNodeModel.setUserName(taskContent);
                        }
                    }
                    else{
                        if(flag){
                            flowTaskNodeModel.setCompletion(1);
                            flowTaskNodeModel.setType("0");

                            if(historicActivityInstance.getActivityType().equals("userTask")){
                                HistoricActivityInstance finalHistoricActivityInstance = historicActivityInstance;
                                UserEntity user = serviceUtilUserName.stream().filter(t -> t.getId().equals(finalHistoricActivityInstance.getAssignee())).findFirst().orElse(null);
                                if (user != null) {
                                    flowTaskNodeModel.setUserName(user.getRealName() + "/" + user.getAccount());
                                } else {
                                    String documentation = flowNode.getDocumentation();
                                    if(StringUtils.isBlank(documentation)){
                                        flowTaskNodeModel.setUserName(flowNode.getName());
                                    }
                                    else{
                                        String taskContent=documentation.split(taskDescriptionSeparator)[0];
                                        flowTaskNodeModel.setUserName(taskContent);
                                    }
                                }
                            }
                            else{
                                String documentation = flowNode.getDocumentation();
                                if(StringUtils.isBlank(documentation)){
                                    flowTaskNodeModel.setUserName(flowNode.getName());
                                }
                                else{
                                    String taskContent=documentation.split(taskDescriptionSeparator)[0];
                                    flowTaskNodeModel.setUserName(taskContent);
                                }
                            }
                        }
                        else{
                            flowTaskNodeModel.setCompletion(0);
                            flowTaskNodeModel.setType("1");
                            String documentation = flowNode.getDocumentation();
                            if(StringUtils.isBlank(documentation)){
                                flowTaskNodeModel.setUserName(flowNode.getName());
                            }
                            else{
                                String taskContent=documentation.split(taskDescriptionSeparator)[0];
                                flowTaskNodeModel.setUserName(taskContent);
                            }
                        }
                    }
                }

                if(activityBehavior instanceof UserTaskActivityBehavior){
                    flowTaskNodeModel.setId(flowElement.getId());
                    flowTaskNodeModel.setNodeCode(flowElement.getId());
                    flowTaskNodeModel.setNodeName(flowElement.getName());
                    if(destination.getId().equals(flowElement.getId())){
                        flowTaskNodeModel.setNodeType(FlowNodeTypeEnum.START.getType());
                    }
                    else{
                        flowTaskNodeModel.setNodeType(FlowNodeTypeEnum.APPROVER.getType());
                    }
                    flowTaskNodeModel.setTaskId(historicProcessInstance.getId());
                    if(historicActivityInstance==null){
                        TaskNodeModel taskNodeModel = new TaskNodeModel();
                        taskNodeModel.setId(flowElement.getId());
                        taskNodeModel.setNodeName(flowElement.getName());
                        taskNodeModel.setNodeCode(flowElement.getId());
                        unfinishList.add(taskNodeModel);
                        flowTaskNodeModel.setCreatorTime(new Date().getTime());
                    }
                    else{
                        flowTaskNodeModel.setCreatorTime(historicActivityInstance.getStartTime().getTime());
                    }
                }


                else if(activityBehavior instanceof MultiInstanceActivityBehavior){
                    flowTaskNodeModel.setId(flowElement.getId());
                    flowTaskNodeModel.setNodeCode(flowElement.getId());
                    flowTaskNodeModel.setNodeName(flowElement.getName());
                    if(destination.getId().equals(flowElement.getId())){
                        flowTaskNodeModel.setNodeType(FlowNodeTypeEnum.START.getType());
                    }
                    else{
                        if(flowElement instanceof UserTask){
                            flowTaskNodeModel.setNodeType(FlowNodeTypeEnum.APPROVER.getType());
                        }
                        else if(flowElement instanceof CallActivity){
                            SubFlowDTO subFlowDTO= new SubFlowDTO();
                            subFlowDTO.setIsAsync("1");
                            subFlowDTO.setProcessInstanceId(historicProcessInstance.getId());
                            subFlowDTO.setNodeId(flowElement.getId());
                            flowTaskNodeModel.setId(JsonUtilEx.getObjectToString(subFlowDTO));
                            flowTaskNodeModel.setNodeType(FlowNodeTypeEnum.CALL_ACTIVITY.getType());
                        }

                    }
                    flowTaskNodeModel.setTaskId(historicProcessInstance.getId());
                    if(historicActivityInstance==null){
                        TaskNodeModel taskNodeModel = new TaskNodeModel();
                        taskNodeModel.setId(flowElement.getId());
                        taskNodeModel.setNodeName(flowElement.getName());
                        taskNodeModel.setNodeCode(flowElement.getId());
                        unfinishList.add(taskNodeModel);
                        flowTaskNodeModel.setCreatorTime(new Date().getTime());
                    }
                    else{
                        if(historicActivityInstance.getEndTime()==null){
                            TaskNodeModel taskNodeModel = new TaskNodeModel();
                            taskNodeModel.setId(flowElement.getId());
                            taskNodeModel.setNodeName(flowElement.getName());
                            taskNodeModel.setNodeCode(flowElement.getId());
                            unfinishList.add(taskNodeModel);
                        }
                        flowTaskNodeModel.setCreatorTime(historicActivityInstance.getStartTime().getTime());
                    }
                }
                else if (activityBehavior instanceof ReceiveTaskActivityBehavior){
                    flowTaskNodeModel.setId(flowElement.getId());
                    flowTaskNodeModel.setNodeCode(flowElement.getId());
                    flowTaskNodeModel.setNodeName(flowElement.getName());
                    flowTaskNodeModel.setNodeType(FlowNodeTypeEnum.TIMER.getType());
                    flowTaskNodeModel.setTaskId(historicProcessInstance.getId());
                    if(historicActivityInstance==null){
                        flowTaskNodeModel.setCreatorTime(new Date().getTime());
                    }
                    else{
                        flowTaskNodeModel.setCreatorTime(historicActivityInstance.getStartTime().getTime());
                    }
                }

                else if(activityBehavior instanceof CustomCallActivityActivityBehavior){
                    flowTaskNodeModel.setNodeCode(flowElement.getId());
                    flowTaskNodeModel.setNodeName(flowElement.getName());
                    flowTaskNodeModel.setNodeType(FlowNodeTypeEnum.CALL_ACTIVITY.getType());
                    flowTaskNodeModel.setTaskId(historicProcessInstance.getId());
                    if(historicActivityInstance==null){
                        flowTaskNodeModel.setId(flowElement.getId());
                        flowTaskNodeModel.setCreatorTime(new Date().getTime());
                    }
                    else{
                        flowTaskNodeModel.setId(historicActivityInstance.getCalledProcessInstanceId());
                        flowTaskNodeModel.setCreatorTime(historicActivityInstance.getStartTime().getTime());
                    }
                }

                else if(activityBehavior instanceof CustomManualTaskActivityBehavior){

                    ManualTask  serviceTask =(ManualTask)flowElement;
                    String attributeValueByTaskDefinitionKey = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, serviceTask.getId(), "");
                    Properties properties = JSONObject.parseObject(attributeValueByTaskDefinitionKey, new TypeReference<Properties>() {
                    });
                    Boolean isAsync = properties.getIsAsync();
                    if(isAsync){
                    }
                    else{
                        flowTaskNodeModel.setId(flowElement.getId());
                        flowTaskNodeModel.setNodeCode(flowElement.getId());
                        flowTaskNodeModel.setNodeName(flowElement.getName());

                        flowTaskNodeModel.setNodeType(properties.getNodeType());
                        flowTaskNodeModel.setTaskId(historicProcessInstance.getId());
                        if(historicActivityInstance==null){
                            flowTaskNodeModel.setCreatorTime(new Date().getTime());
                        }
                        else{
                            flowTaskNodeModel.setCreatorTime(historicActivityInstance.getStartTime().getTime());
                        }
                    }
                }


                else if (activityBehavior instanceof NoneEndEventActivityBehavior){
                    flowTaskNodeModel.setId(flowElement.getId());
                    flowTaskNodeModel.setNodeCode(flowElement.getId());
                    flowTaskNodeModel.setNodeName("结束");
                    flowTaskNodeModel.setNodeType("endround");
                    flowTaskNodeModel.setTaskId(historicProcessInstance.getId());
                    if(historicActivityInstance==null){
                        flowTaskNodeModel.setCreatorTime(new Date().getTime());
                    }
                    else{
                        flowTaskNodeModel.setCreatorTime(historicActivityInstance.getStartTime().getTime());
                    }
                }
                flowTaskNodeListAll.add(flowTaskNodeModel);
            }
            vo.setFlowTaskNodeList(flowTaskNodeListAll);
            vo.setNodeModelList(unfinishList);

            for (FlowTaskOperatorRecordEntity entity : operatorRecordList) {
                if(StringUtils.isBlank(entity.getHandleId()) &&StringUtils.isNotBlank(entity.getOperatorId())){
                    entity.setHandleId(entity.getOperatorId());
                }
                FlowTaskOperatorRecordModel infoModel = JsonUtil.getJsonToBean(entity, FlowTaskOperatorRecordModel.class);
                UserEntity operatorName = serviceUtilUserName.stream().filter(t -> t.getId().equals(entity.getOperatorId())).findFirst().orElse(null);
                infoModel.setOperatorId(operatorName != null ? operatorName.getRealName() + "/" + operatorName.getAccount() : "");
                UserEntity userName = serviceUtilUserName.stream().filter(t -> t.getId().equals(entity.getHandleId())).findFirst().orElse(null);
                infoModel.setUserName(userName != null ? userName.getRealName() + "/" + userName.getAccount() : "");
                if(entity.getReceiveTime()!=null){
                    infoModel.setCreatorTime(entity.getReceiveTime().getTime());
                }
                if(StringUtils.isNotBlank(entity.getTaskNodeId())){
//                    HistoricActivityInstance historicActivityInstance = historicActivityInstanceMap.get(entity.getTaskNodeId());
//                    if(FlowRecordEnum.DOING.getCode().equals(infoModel.getHandleStatus()) && historicActivityInstance.getEndTime()!=null){
//                        infoModel.setHandleStatus(FlowRecordEnum.COMPLETE.getCode());
//                    }
                }
                recordList.add(infoModel);
            }
            vo.setFlowTaskOperatorRecordList(recordList);



            //获取当前节点
            if (StringUtil.isNotEmpty(taskNodeId)) {
                HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().taskId(taskNodeId).singleResult();
                bpmnModelMainProcess=getBpmnModelMainProcess(task.getProcessDefinitionId());
                String property = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, task.getTaskDefinitionKey(), "userTask");
                Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
                });
                UserTask firstNode = getFirstNode(bpmnModelMainProcess);
                if(firstNode.getId().equals(task.getTaskDefinitionKey())){
                    properties.setHasAuditBtn(Boolean.TRUE);
                    properties.setAuditBtnText(properties.getSubmitBtnText());
                    properties.setHasSaveBtn(Boolean.FALSE);
                    properties.setHasCancelBtn(Boolean.FALSE);
                    properties.setHasAbstentionBtn(Boolean.FALSE);
                    properties.setHasRejectBtn(Boolean.FALSE);
                    properties.setHasRevokeBtn(Boolean.FALSE);
                    properties.setHasTransferBtn(Boolean.FALSE);
                    properties.setHasInvokeBtn(Boolean.FALSE);
                    properties.setHasCopyBtn(Boolean.FALSE);
                    properties.setHasTerminationBtn(Boolean.FALSE);
                    properties.setHasMultiAddBtn(Boolean.FALSE);
                    properties.setHasLockOrUnLockBtn(Boolean.FALSE);
                    properties.setHasAssistBtn(Boolean.FALSE);
                    properties.setHasMultiRemoveBtn(Boolean.FALSE);
                    properties.setHasFreeApproverBtn(Boolean.FALSE);
                    vo.setApproversProperties(properties);
                }
                else{
                    if(null==task.getEndTime()){
                        org.flowable.task.api.Task invokeTask = taskService.createTaskQuery().taskId(task.getId()).singleResult();
                        if(StringUtils.isBlank(invokeTask.getParentTaskId())){
                            if(invokeTask.getDelegationState()== DelegationState.PENDING){
                                properties.setHasInvokeBtn(Boolean.FALSE);
                            }
                        }
                        else{
                            properties.setHasSaveBtn(Boolean.FALSE);
                            properties.setHasAuditBtn(Boolean.FALSE);
                            properties.setHasCancelBtn(Boolean.FALSE);
                            properties.setHasAbstentionBtn(Boolean.FALSE);
                            properties.setHasRejectBtn(Boolean.FALSE);
                            properties.setHasRevokeBtn(Boolean.FALSE);
                            properties.setHasTransferBtn(Boolean.FALSE);
                            properties.setHasInvokeBtn(Boolean.FALSE);
                            properties.setHasCopyBtn(Boolean.FALSE);
                            properties.setHasTerminationBtn(Boolean.FALSE);
                            properties.setHasMultiAddBtn(Boolean.FALSE);
                            properties.setHasLockOrUnLockBtn(Boolean.FALSE);
                            properties.setHasAssistBtn(Boolean.FALSE);
                            properties.setHasMultiRemoveBtn(Boolean.FALSE);
                            properties.setHasFreeApproverBtn(Boolean.FALSE);
                            vo.setApproversProperties(properties);
                        }
                    }
                    vo.setApproversProperties(properties);
                }

                vo.setFormOperates(properties.getFormOperates());
                String formKey = task.getFormKey();
                String[] split = formKey.split(taskDescriptionSeparator);
                formId = split[0];
                Map<String, Object> formDataMap = flowTaskUtil.infoData(split[0], split[1]);
                vo.setFormData(formDataMap);
                vo.getFlowTaskInfo().setFlowFormContentJson(JsonUtil.getObjectToString(formDataMap));
                List<FlowTaskOperatorRecordModel> flowTaskOperatorRecordList = vo.getFlowTaskOperatorRecordList();
                for (FlowTaskOperatorRecordModel flowTaskOperatorRecordModel : flowTaskOperatorRecordList) {
//                    if(flowTaskOperatorRecordModel.getTaskNodeId().equals(taskNodeId)){
//                        flowTaskOperatorRecordModel.setDraftData(JsonUtil.getObjectToString(formDataMap));
//                    }
                    if(StringUtils.isNotBlank(flowTaskOperatorRecordModel.getTaskNodeId())){
                        if(flowTaskOperatorRecordModel.getTaskNodeId().equals(taskNodeId)){
                            flowTaskOperatorRecordModel.setDraftData(JsonUtil.getObjectToString(formDataMap));
                        }
                    }
                }
                LambdaQueryWrapper<FlowTaskOperatorEntity> flowTaskOperatorEntityLambdaQueryWrapper= new LambdaQueryWrapper<>();
                flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId());
                flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
                FlowTaskOperatorEntity operatorEntity = flowTaskOperatorService.getOne(flowTaskOperatorEntityLambdaQueryWrapper);
                if(operatorEntity==null){
                    //只可能是流程监控页面
                    flowTaskOperatorEntityLambdaQueryWrapper.clear();
                    flowTaskOperatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId());
                    operatorEntity=flowTaskOperatorService.list(flowTaskOperatorEntityLambdaQueryWrapper).get(0);
                }

                if(task.getEndTime()==null){
                    if(operatorEntity!=null){
                        vo.setDraftData(JsonUtil.stringToMap(operatorEntity.getDraftData()));
                    }
                }
                else{
                    vo.setDraftData(null);
                }

            }

            //流程监控权限
            if (!userInfo.getIsAdministrator()) {
                vo.setNoOperateAuth(true);
//                List<String> organizeUserList = serviceUtil.getOrganizeUserList("edit");
//                vo.setNoOperateAuth(!organizeUserList.contains(MapUtil.getStr(processVariables,APPLY_USER_ID)));
            }
        }
        //流程还没有发起
        else{
            if("0".equals(id)){
                //流程任务
                FlowTaskModel flowTaskModel = new FlowTaskModel();
                flowTaskModel.setSuspend(false);
                vo.setFlowTaskInfo(flowTaskModel);
            }
        }
        FlowFormEntity form = serviceUtil.getForm(formId);
        vo.setFlowFormInfo(JsonUtil.getJsonToBean(form, FlowFormVo.class));
        if(historicProcessInstance!=null){
            LambdaQueryWrapper<FlowAddNodeTemplateEntity> flowAddNodeTemplateEntityLambdaQueryWrapper= new LambdaQueryWrapper<>();
            flowAddNodeTemplateEntityLambdaQueryWrapper.eq(FlowAddNodeTemplateEntity::getProcessInstanceId,historicProcessInstance.getId());
            FlowAddNodeTemplateEntity flowAddNodeTemplateEntity = flowAddNodeTemplateEntityService.getOne(flowAddNodeTemplateEntityLambdaQueryWrapper);
            if(flowAddNodeTemplateEntity!=null){
                templateJson.setFlowTemplateJson(flowAddNodeTemplateEntity.getModelContent());
            }
        }

        FlowTemplateModel templateModel = JsonUtil.getJsonToBean(templateJson, FlowTemplateModel.class);
        templateModel.setType(template.getType());
        templateModel.setFullName(template.getFullName());
        vo.setFlowTemplateInfo(templateModel);

        return vo;
    }

    @Override
    public List<FlowSummary> recordList(String id, String category, String type) {
        //审批汇总
        List<Integer> handleStatus = new ArrayList<>();
        if (!"0".equals(type)) {
            handleStatus.add(0);
            handleStatus.add(1);
        }

        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult();
        if(historicTaskInstance==null){
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(id).singleResult();
            if(historicProcessInstance==null){

            }
            else{
                id=historicProcessInstance.getId();
            }
        }
        else{
            id=historicTaskInstance.getProcessInstanceId();
        }

        List<FlowTaskOperatorRecordEntity> recordListAll = flowTaskOperatorRecordService.getRecordList(id, handleStatus);
        List<String> userIdAll = new ArrayList<>();
        List<String> userIdList = recordListAll.stream().map(FlowTaskOperatorRecordEntity::getHandleId).collect(Collectors.toList());
        List<String> operatorId = recordListAll.stream().filter(t -> StringUtil.isNotEmpty(t.getOperatorId())).map(FlowTaskOperatorRecordEntity::getOperatorId).collect(Collectors.toList());
        userIdAll.addAll(userIdList);
        userIdAll.addAll(operatorId);
        List<UserEntity> userList = serviceUtil.getUserName(userIdAll);
        List<FlowSummary> list = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        Map<String, List<FlowTaskOperatorRecordEntity>> operatorAll = new HashMap<>();
        if (FlowRecordListEnum.position.getCode().equals(category)) {
            List<String> userId = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
            List<UserRelationEntity> relationList = serviceUtil.getListByUserIdAll(userId);
            List<String> objectId = relationList.stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
            List<PositionEntity> positionListAll = serviceUtil.getPositionName(objectId);
            for (PositionEntity entity : positionListAll) {
                map.put(entity.getId(), entity.getFullName());
                List<String> userAll = relationList.stream().filter(t -> t.getObjectId().equals(entity.getId())).map(UserRelationEntity::getUserId).collect(Collectors.toList());
                List<FlowTaskOperatorRecordEntity> operator = new ArrayList<>();
                for (FlowTaskOperatorRecordEntity recordEntity : recordListAll) {
                    if (userAll.contains(recordEntity.getHandleId())) {
                        operator.add(recordEntity);
                    }
                }
                operatorAll.put(entity.getId(), operator);
            }
        } else if (FlowRecordListEnum.role.getCode().equals(category)) {
            List<String> userId = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
            List<UserRelationEntity> relationList = serviceUtil.getListByUserIdAll(userId);
            List<String> objectId = relationList.stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
            List<RoleEntity> roleListAll = serviceUtil.getListByIds(objectId);
            for (RoleEntity entity : roleListAll) {
                map.put(entity.getId(), entity.getFullName());
                List<String> userAll = relationList.stream().filter(t -> t.getObjectId().equals(entity.getId())).map(UserRelationEntity::getUserId).collect(Collectors.toList());
                List<FlowTaskOperatorRecordEntity> operator = new ArrayList<>();
                for (FlowTaskOperatorRecordEntity recordEntity : recordListAll) {
                    if (userAll.contains(recordEntity.getHandleId())) {
                        operator.add(recordEntity);
                    }
                }
                operatorAll.put(entity.getId(), operator);
            }
        } else if (FlowRecordListEnum.department.getCode().equals(category)) {
            List<String> organizeList = userList.stream().map(UserEntity::getOrganizeId).collect(Collectors.toList());
            List<OrganizeEntity> organizeListAll = serviceUtil.getOrganizeName(organizeList);
            for (OrganizeEntity entity : organizeListAll) {
                map.put(entity.getId(), entity.getFullName());
                List<String> userAll = userList.stream().filter(t -> t.getOrganizeId().equals(entity.getId())).map(UserEntity::getId).collect(Collectors.toList());
                List<FlowTaskOperatorRecordEntity> operator = new ArrayList<>();
                for (FlowTaskOperatorRecordEntity recordEntity : recordListAll) {
                    if (userAll.contains(recordEntity.getHandleId())) {
                        operator.add(recordEntity);
                    }
                }
                operatorAll.put(entity.getId(), operator);
            }
        }
        for (String key : map.keySet()) {
            String fullName = map.get(key);
            FlowSummary summary = new FlowSummary();
            summary.setId(key);
            summary.setFullName(fullName);
            List<FlowTaskOperatorRecordEntity> recordList = operatorAll.get(key);
            List<FlowSummary> childList = new ArrayList<>();
            for (FlowTaskOperatorRecordEntity entity : recordList) {
                FlowSummary childSummary = JsonUtil.getJsonToBean(entity, FlowSummary.class);
                UserEntity user = userList.stream().filter(t -> t.getId().equals(entity.getHandleId())).findFirst().orElse(null);
                childSummary.setUserName(user != null ? user.getRealName() + "/" + user.getAccount() : "");
                UserEntity userEntity = userList.stream().filter(t -> t.getId().equals(entity.getOperatorId())).findFirst().orElse(null);
                childSummary.setOperatorId(userEntity != null ? userEntity.getRealName() + "/" + userEntity.getAccount() : "");
                childSummary.setHeadIcon(UploaderUtil.uploaderImg(user.getHeadIcon()));
                childList.add(childSummary);
            }
            summary.setList(childList);
            list.add(summary);
        }
        return list;
    }

    @Override
    public boolean press(String id, FlowModel flowModel) throws WorkFlowException {
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(id).includeProcessVariables().singleResult();
        Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
        String templateJsonId = MapUtil.getStr(processVariables, FLOW_TEMPLATE_JSON_ID);
        Process bpmnModelMainProcess = getBpmnModelMainProcess(historicProcessInstance.getProcessDefinitionId());
        List<String> nodeList = activitiUtils.getCurrentNodeIdOnlyUserTaskList(historicProcessInstance.getId());
        List<FlowElement> flowElementList = new ArrayList<>();
        for (String activeActivityId : nodeList) {
            FlowElement flowElement = bpmnModelMainProcess.getFlowElement(activeActivityId);
            if(flowElement instanceof UserTask){
                flowElementList.add(flowElement);
            }
        }

        if(CollUtil.isNotEmpty(flowElementList)){
            for (FlowElement flowElement : flowElementList) {
                //1.3调用通知
                Properties firstNodeProperty = getFirstNodeProperty(historicProcessInstance.getProcessDefinitionId());
                String taskProperty = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, flowElement.getId(), "userTask");
                Properties properties = JSONObject.parseObject(taskProperty, new TypeReference<Properties>() {
                });

                MsgConfig waitMsgConfig = properties.getWaitMsgConfig();
                Integer on = waitMsgConfig.getOn();


                Boolean messageFlag=false;
                if(on!=0){
                    messageFlag=true;
                }

                if(messageFlag){
                    List<org.flowable.task.api.Task> list = taskService.createNativeTaskQuery()
                            .sql("SELECT ID_,TASK_DEF_KEY_,FORM_KEY_ FROM ACT_RU_TASK WHERE PROC_INST_ID_ =#{procInstId} AND TASK_DEF_KEY_ =#{key}")
                            .parameter("procInstId", historicProcessInstance.getId())
                            .parameter("key", flowElement.getId()).list();
                    List<String> taskIds = new ArrayList<>();
                    for (org.flowable.task.api.Task task : list) {
                        taskIds.add(task.getId());
                    }

                    LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.in(FlowTaskOperatorEntity::getTaskNodeId, taskIds);
                    List<FlowTaskOperatorEntity> flowTaskOperatorEntityList = flowTaskOperatorService.list(lambdaQueryWrapper);

                    FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(templateJsonId);
                    FlowMsgModel flowMsgModel = new FlowMsgModel();
                    flowMsgModel.setStartNodeProperties(firstNodeProperty);
                    flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
                    flowMsgModel.setOperatorList(flowTaskOperatorEntityList);
                    String formKey = list.get(0).getFormKey();
                    //索引0 是 formId,  1是 业务主键
                    String[] split = formKey.split(BasicActivitiConstants.taskDescriptionSeparator);
                    Map<String, Object> result = flowTaskUtil.infoData(split[0], split[1]);
                    flowMsgModel.setData(result);
//                    flowMsgModel.setFlowModel(flowModel);
                    FlowTaskDTO flowTask = new FlowTaskDTO();
                    flowTask.setCreatorUserId(MapUtil.getStr(processVariables, APPLY_USER_ID));
                    flowTask.setStatus(MapUtil.getInt(processVariables, PROCESS_STATUS));
                    flowTask.setFullName(MapUtil.getStr(processVariables, BUSINESS_TITLE));
                    flowMsgModel.setTaskEntity(flowTask);

                    FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
                    flowTaskNodeDTO.setTaskId(historicProcessInstance.getId());
                    flowTaskNodeDTO.setTaskNodeId(list.get(0).getId());
                    flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);
                    flowMsgModel.setFlowModel(flowModel);
                    flowMsgModel.setFlowTemplateAllModel(templateAllModel);
                    flowMsgModel.setTaskId(historicProcessInstance.getId());
                    flowMsgModel.setTaskNodeId(list.get(0).getId());
                    flowMsgUtil.message(flowMsgModel);
                }

            }
        }

/*        FlowTaskEntity flowTaskEntity = flowTaskService.getInfo(id,
                FlowTaskEntity::getId, FlowTaskEntity::getFullName, FlowTaskEntity::getStatus,
                FlowTaskEntity::getCreatorUserId, FlowTaskEntity::getFlowId
        );
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowTaskEntity.getFlowId());
        Map<String, Object> data = flowTaskUtil.startData(templateAllModel, flowTaskEntity);
        List<FlowTaskOperatorEntity> operatorList = flowTaskOperatorService.press(id);
        boolean flag = operatorList.size() > 0;
        TaskNodeListModel taskNodeListModel = TaskNodeListModel.builder().id(id).state(FlowNodeEnum.Process.getCode()).build();
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(taskNodeListModel,
                FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getNodePropertyJson,
                FlowTaskNodeEntity::getNodeCode, FlowTaskNodeEntity::getNodeName,
                FlowTaskNodeEntity::getNodeType, FlowTaskNodeEntity::getFormId
        );
        //发送消息
        FlowMsgModel flowMsgModel = new FlowMsgModel();
        flowMsgModel.setNodeList(taskNodeList);
        flowMsgModel.setOperatorList(operatorList);
        flowMsgModel.setTaskEntity(flowTaskEntity);
        flowMsgModel.setData(data);
        flowMsgModel.setFlowTemplateAllModel(templateAllModel);
        flowMsgModel.setFlowModel(flowModel);
        flowMsgUtil.message(flowMsgModel);
        return flag;*/
        return true;
    }

    @Override
    public FlowCandidateVO candidates(String id, FlowModel flowModel, boolean batch) throws WorkFlowException {
        //此接口目前只能在  我发起页面 以及待办页面被调用到  那么也就意味着这个id 要么是0  要么是流程实例id 要么是任务id
        String flowId = flowModel.getFlowId();
        FlowTemplateJsonEntity flowTemplateJsonEntity = flowTemplateJsonService.getById(flowId);
        Map<String, Object> formData = flowModel.getFormData();
//        formData.put("flag",true);
        if("0".equals(id)){
            return getCandidateVos(flowTemplateJsonEntity.getProcessDefinitionId(),"",formData,false,id);
        }
        else{
            org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(id).includeProcessVariables().singleResult();
            if(task==null) {
                return getCandidateVos(flowTemplateJsonEntity.getProcessDefinitionId(), "", formData,batch,id);
            }
            else{
                Map<String, Object> processVariables = task.getProcessVariables();
                formData.putAll(processVariables);
                return getCandidateVos(flowTemplateJsonEntity.getProcessDefinitionId(), task.getTaskDefinitionKey(), formData,batch,id);
            }
        }
    }
    private FlowCandidateVO getCandidateVos(String processDefinitionId,String taskDefinitionKey,
                                            Map<String,Object> formInfoMap,Boolean batch,String id){
        Map<String, Object> processVariables = new HashMap<>();
        processVariables.putAll(formInfoMap);
        Date date = MapUtil.get(processVariables, CURRENT_CREATE_TIME, Date.class);
        if(date==null){
            date=new Date();
            processVariables.put(JnpfKeyConsts.CREATETIME, date.getTime() + "");
        }
        String applyUserId = MapUtil.getStr(processVariables, APPLY_USER_ID);
        if(StringUtils.isBlank(applyUserId)){
            applyUserId=userProvider.get().getUserId();
            processVariables.put(APPLY_USER_ID,applyUserId);
            processVariables.put(JnpfKeyConsts.CREATEUSER,applyUserId);
            UserEntity userEntity = userService.getInfo(applyUserId);
            processVariables.put(JnpfKeyConsts.CURRORGANIZE,userEntity.getOrganizeId());
            processVariables.put(JnpfKeyConsts.CURRPOSITION,userEntity.getPositionId());
            processVariables.put(JnpfKeyConsts.MODIFYTIME,date);
            processVariables.put(JnpfKeyConsts.MODIFYUSER,applyUserId);
        }

        if("0".equals(id)){
            ExecutionEntityImpl execution=  new ExecutionEntityImpl();
            execution.setTransientVariables(processVariables);
            execution.setProcessDefinitionId(processDefinitionId);
            processVariables.put("execution",execution);
        }


        List<FlowCandidateListModel> nextNodeList = getNextNodeList(
                processDefinitionId, taskDefinitionKey, processVariables,batch);
        FlowCandidateVO flowCandidateVO  = new FlowCandidateVO();
        if(CollUtil.isEmpty(nextNodeList)){
            flowCandidateVO.setList(new ArrayList<>());
            flowCandidateVO.setType(3);
        }
        else{
            String rejectNodeStr = MapUtil.getStr(formInfoMap, REJECT_NODE);
            if(StringUtils.isBlank(rejectNodeStr)){
                flowCandidateVO.setList(nextNodeList);
                Integer branFlowCount=0;
                Integer candidatesCount=0;
                for (FlowCandidateListModel flowCandidateListModel : nextNodeList) {
                    if(Boolean.TRUE.equals(flowCandidateListModel.getIsCandidates())){
                        candidatesCount+=1;
                    }
                    if(Boolean.TRUE.equals(flowCandidateListModel.getIsBranchFlow())){
                        branFlowCount+=1;
                    }
                }
                if(branFlowCount>0){
                    flowCandidateVO.setType(1);
                }
                else{
                    if(candidatesCount>0){
                        flowCandidateVO.setType(2);
                    }
                    else{
                        flowCandidateVO.setType(3);
                    }
                }
            }
            else{
                List<String> nodeList= new ArrayList<>();
                for (FlowCandidateListModel flowCandidateListModel : nextNodeList) {
                    nodeList.add(flowCandidateListModel.getNodeId());
                }
                List<String> rejectList = Arrays.asList(rejectNodeStr.split(","));
                Collection<String> intersection = CollUtil.intersection(nodeList, rejectList);
                if(CollUtil.isEmpty(intersection)){
                    flowCandidateVO.setType(3);
                    return flowCandidateVO;
                }
                else{
                    flowCandidateVO.setList(nextNodeList);
                    Integer branFlowCount=0;
                    Integer candidatesCount=0;
                    for (FlowCandidateListModel flowCandidateListModel : nextNodeList) {
                        if(Boolean.TRUE.equals(flowCandidateListModel.getIsCandidates())){
                            candidatesCount+=1;
                        }
                        if(Boolean.TRUE.equals(flowCandidateListModel.getIsBranchFlow())){
                            branFlowCount+=1;
                        }
                    }
                    if(branFlowCount>0){
                        flowCandidateVO.setType(1);
                    }
                    else{
                        if(candidatesCount>0){
                            flowCandidateVO.setType(2);
                        }
                        else{
                            flowCandidateVO.setType(3);
                        }
                    }
                }
            }

        }

        return flowCandidateVO;
    }

    public List<FlowCandidateListModel> getNextNodeList(String procDefId, String nodeId, Map<String, Object> dataMap,Boolean batch) {
        List<FlowCandidateListModel> flowCandidateListModels = new ArrayList<>();
        Process process = getBpmnModelMainProcess(procDefId);
        Collection<FlowElement> flowElements = process.getFlowElements();
        FlowNode currentFlowElement = null;

        if (StringUtils.isEmpty(nodeId)) {
            currentFlowElement=BpmnModelUtils.getFirstNode(process);
        } else {
            currentFlowElement = (FlowNode) BpmnModelUtils.getFlowElementById(nodeId, flowElements);
        }
        List<SequenceFlow> outgoingFlows = currentFlowElement.getOutgoingFlows();
        for (SequenceFlow outgoingFlow : outgoingFlows) {
            getNextNode(procDefId, outgoingFlow.getTargetFlowElement(), dataMap, flowCandidateListModels,false,batch);
        }
        return flowCandidateListModels;
    }

    private void getNextNode(String definitionId, FlowElement flowElement, Map<String, Object> map,
                             List<FlowCandidateListModel> nextUserTask,Boolean branchFlowFlag,Boolean batch) {
        Process process = getBpmnModelMainProcess(definitionId);
        //如果是结束节点
        if (flowElement instanceof EndEvent) {
            return ;
        }
        List<SequenceFlow> outGoingFlows = null;
        if (flowElement instanceof org.flowable.bpmn.model.Task) {
            if(flowElement instanceof UserTask){
                FlowCandidateListModel flowCandidateListModel = new FlowCandidateListModel();
                flowCandidateListModel.setNodeId(flowElement.getId());
                flowCandidateListModel.setNodeName(flowElement.getName());
                String property = getAttributeValueByTaskDefinitionKey(process, flowElement.getId(), "userTask");
                Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
                });
                Integer assigneeType = properties.getAssigneeType();
                Integer initiateType = properties.getInitiateType();
                boolean isCandidates = (FlowTaskOperatorEnum.Candidate.getCode().equals(initiateType) || FlowTaskOperatorEnum.Candidate.getCode().equals(assigneeType));
                flowCandidateListModel.setIsCandidates(isCandidates);
                Object flag = map.get("flag");
                if(branchFlowFlag &&batch){
                    throw new WorkFlowException("");
                }
                if(branchFlowFlag){
                    flowCandidateListModel.setIsBranchFlow(Boolean.TRUE);
                }
                else{
                    flowCandidateListModel.setIsBranchFlow(Boolean.FALSE);
                }
                if (isCandidates) {
                    List<String> list = new ArrayList<>();
                    list.addAll(properties.getApprovers());
                    List<String> handleIdAll = serviceUtil.getUserListAll(list);
                    list.addAll(handleIdAll);
                    Pagination pagination = new Pagination();
                    List<UserEntity> userName = serviceUtil.getUserName(list, pagination);
                    flowCandidateListModel.setHasCandidates(userName.size() > 0);
                }
                nextUserTask.add(flowCandidateListModel);


                if(flag!=null &&Boolean.TRUE.equals(Boolean.parseBoolean(flag.toString()))){
                    List<SequenceFlow> outgoingFlows = ((UserTask) flowElement).getOutgoingFlows();
                    if(CollUtil.isNotEmpty(outgoingFlows)){
                        for (SequenceFlow outgoingFlow : outgoingFlows) {
                            getNextNode(definitionId,outgoingFlow.getTargetFlowElement(),map,nextUserTask,false,batch);
                        }
                    }
                }
            }
        }
        else if(flowElement instanceof ExclusiveGateway){
            outGoingFlows = ((Gateway) flowElement).getOutgoingFlows();
            //需要判断是开始网关 还是结束网关
            String gatewayId = flowElement.getId();
            if(gatewayId.contains("end")){
                for (SequenceFlow goingFlow : outGoingFlows) {
                    getNextNode(definitionId,goingFlow.getTargetFlowElement(),map,nextUserTask,false,batch);
                }
            }
            else{
                //默认条件有可能为空
                String exDefaultFlow = ((ExclusiveGateway) flowElement).getDefaultFlow();

                List<SequenceFlow> tempOutGoingFlows=new ArrayList<>();
                List<SequenceFlow> outgoingFlows = ((ExclusiveGateway) flowElement).getOutgoingFlows();
                Map<String,SequenceFlow> sequenceFlowMap = new LinkedHashMap<>();
                for (SequenceFlow outgoingFlow : outgoingFlows) {
                    sequenceFlowMap.put(outgoingFlow.getId(),outgoingFlow);
                }
                if(StringUtils.isNotBlank(exDefaultFlow)){
                    sequenceFlowMap.remove(exDefaultFlow);
                }
                //需要判断是正常分支还是   选择分支
                if(gatewayId.contains("branchFlow")){
                    //代表是选择分支 那么不需要计算条件 下面第一个节点必定是userTask
                    for (SequenceFlow outgoingFlow : outgoingFlows) {
                        getNextNode(definitionId,outgoingFlow.getTargetFlowElement(),map,nextUserTask,true,batch);
                    }
                }
                else{
                    //普通条件分支
                    Boolean result=false;
                    SequenceFlow trueSequenceFlow=null;
                    for (SequenceFlow outgoingFlow : sequenceFlowMap.values()) {
                        String property = getAttributeValueByTaskDefinitionKey(process, outgoingFlow.getId(), "sequenceFlow");
                        Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
                        });
                        //兼容Vue3版本
                        Integer modeFlag = properties.getModeFlag();
                        Boolean b=false;
                        if(null==modeFlag){
                            List<ProperCond> conditions = properties.getConditions();
                            FlowConditionModel flowConditionModel = new FlowConditionModel();
                            if(map.containsKey("execution")){
                                map.remove("execution");
                            }
                            String data = JsonUtil.getObjectToString(map);
                            flowConditionModel.setData(data);
                            flowConditionModel.setUserInfo(userProvider.get());
                            flowConditionModel.setUserEntity(userService.getInfo(MapUtil.getStr(map,APPLY_USER_ID)));
                            flowConditionModel.setVariablesMap(map);
                            b = nodeConditionDecide(flowConditionModel, properties);
                        }
                        else{
                            String conditionExpression = outgoingFlow.getConditionExpression();
                            b = managementService.executeCommand(new ExpressionCmd("", conditionExpression, map));
                        }


                        if(b){
                            result=true;
                            trueSequenceFlow=outgoingFlow;
                            break;
                        }
                    }
                    //如果 条件都是false 且没有 默认分支
                    if(!result){
                        //
                        if(StringUtils.isNotBlank(exDefaultFlow)){
                            SequenceFlow defaultFlowEx = (SequenceFlow) process.getFlowElement(exDefaultFlow);
                            getNextNode(definitionId,defaultFlowEx.getTargetFlowElement(),map,nextUserTask,false,batch);
                        }
                    }
                    else{
                        getNextNode(definitionId,trueSequenceFlow.getTargetFlowElement(),map,nextUserTask,false,batch);
                    }

                }
            }


        }
        else if (flowElement instanceof StartEvent) {
            outGoingFlows = ((StartEvent) flowElement).getOutgoingFlows();
        }
        else if(flowElement instanceof ParallelGateway) {
            outGoingFlows = ((Gateway) flowElement).getOutgoingFlows();
            for (SequenceFlow outgoingFlow : outGoingFlows) {
                getNextNode(definitionId, outgoingFlow.getTargetFlowElement(), map, nextUserTask, false, batch);
            }
        }
        else if(flowElement instanceof InclusiveGateway){
            outGoingFlows = ((Gateway) flowElement).getOutgoingFlows();
            String gatewayId = flowElement.getId();
            if(gatewayId.contains("end")){
                for (SequenceFlow goingFlow : outGoingFlows) {
                    getNextNode(definitionId,goingFlow.getTargetFlowElement(),map,nextUserTask,false,batch);
                }
            }
            else{
                String exDefaultFlow = ((InclusiveGateway) flowElement).getDefaultFlow();

                List<SequenceFlow> tempOutGoingFlows=new ArrayList<>();
                List<SequenceFlow> outgoingFlows = ((InclusiveGateway) flowElement).getOutgoingFlows();
                Map<String,SequenceFlow> sequenceFlowMap = new HashMap<>();
                for (SequenceFlow outgoingFlow : outgoingFlows) {
                    sequenceFlowMap.put(outgoingFlow.getId(),outgoingFlow);
                }
                if(StringUtils.isNotBlank(exDefaultFlow)){
                    sequenceFlowMap.remove(exDefaultFlow);
                }
                if(gatewayId.contains("branchFlow")){
                    for (SequenceFlow outgoingFlow : outgoingFlows) {
                        getNextNode(definitionId,outgoingFlow.getTargetFlowElement(),map,nextUserTask,true,batch);
                    }
                }
                else{
                    //普通条件分支
                    Boolean result=false;
                    List<SequenceFlow> trueSequenceFlows = new ArrayList<>();
                    for (SequenceFlow outgoingFlow : sequenceFlowMap.values()) {
                        String property = getAttributeValueByTaskDefinitionKey(process, outgoingFlow.getId(), "sequenceFlow");
                        Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
                        });
                        List<ProperCond> conditions = properties.getConditions();
                        FlowConditionModel flowConditionModel = new FlowConditionModel();
                        // log.info("序列化流程变量map -> {}", JSONUtil.toJsonStr(map, JSONConfig.create().setIgnoreNullValue(false)));
                        String data = JSONUtil.toJsonStr(map, JSONConfig.create().setIgnoreNullValue(false));
                        flowConditionModel.setData(data);
                        flowConditionModel.setUserInfo(userProvider.get());
                        flowConditionModel.setUserEntity(userService.getInfo(MapUtil.getStr(map,APPLY_USER_ID)));
                        flowConditionModel.setVariablesMap(map);

                        boolean b = nodeConditionDecide(flowConditionModel, properties);
                        if(b){
                            result=true;
                            trueSequenceFlows.add(outgoingFlow);
//                                    break;
                        }
                    }
                    if(!result){
                        //
                        if(StringUtils.isNotBlank(exDefaultFlow)){
                            SequenceFlow defaultFlowEx = (SequenceFlow) process.getFlowElement(exDefaultFlow);
                            getNextNode(definitionId,defaultFlowEx.getTargetFlowElement(),map,nextUserTask,false,batch);
                        }
                    }
                    else{
                        for (SequenceFlow trueSequenceFlow : trueSequenceFlows) {
                            getNextNode(definitionId,trueSequenceFlow.getTargetFlowElement(),map,nextUserTask,false,batch);
                        }
                    }

                }
            }
        }
        else if (flowElement instanceof SubProcess) {
            outGoingFlows = ((SubProcess) flowElement).getOutgoingFlows();
        }
        else if(flowElement instanceof CallActivity){
            FlowCandidateListModel flowCandidateListModel = new FlowCandidateListModel();
            flowCandidateListModel.setNodeId(flowElement.getId());
            flowCandidateListModel.setNodeName(flowElement.getName());
            String property = getAttributeValueByTaskDefinitionKey(process, flowElement.getId(), "callActivity");
            Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
            });
            Integer assigneeType = properties.getAssigneeType();
            Integer initiateType = properties.getInitiateType();
            boolean isCandidates = (FlowTaskOperatorEnum.Candidate.getCode().equals(initiateType) || FlowTaskOperatorEnum.Candidate.getCode().equals(assigneeType));
            flowCandidateListModel.setIsCandidates(isCandidates);
            if(branchFlowFlag &&batch){
                throw new WorkFlowException("");
            }
            if(branchFlowFlag){
                flowCandidateListModel.setIsBranchFlow(Boolean.TRUE);
            }
            else{
                flowCandidateListModel.setIsBranchFlow(Boolean.FALSE);
            }
            if (isCandidates) {
                List<String> list = new ArrayList<>();
                list.addAll(properties.getApprovers());
                List<String> handleIdAll = serviceUtil.getUserListAll(list);
                list.addAll(handleIdAll);
                Pagination pagination = new Pagination();
                List<UserEntity> userName = serviceUtil.getUserName(list, pagination);
                flowCandidateListModel.setHasCandidates(userName.size() > 0);
            }
            nextUserTask.add(flowCandidateListModel);
        }
    }

    private static boolean nodeConditionDecide(FlowConditionModel conditionModel, Properties properties) {
        String data = conditionModel.getData();
        ScriptEngine scriptEngine = SpringContextHolder.getBean(ScriptEngine.class);
        boolean flag = false;
        Map<String, Object> variablesMap = JsonUtil.stringToMap(data);

        List<ProperCond> conditions = properties.getConditions();
        String matchLogic = properties.getMatchLogic();

        List<String> expressionAll = new ArrayList<>();
        StringBuilder condition = new StringBuilder();
        List<ProperCond> conditionList = properties.getConditions();
        for (int k = 0; k < conditionList.size(); k++) {
            StringBuilder expression = new StringBuilder();
            expression.append("(");
            ProperCond properCond = conditionList.get(k);
            String logic = properCond.getLogic();
            List<GroupsModel> groups = properCond.getGroups();
            for (int i = 0; i < groups.size(); i++) {
                GroupsModel groupsModel = groups.get(i);
                String contain = "!=-1";
                String field = groupsModel.getField();
                String jnpfKey = groupsModel.getJnpfKey();
                int fieldType = groupsModel.getFieldType();
                Object form = fieldType == 1 ? formValue(conditionModel, jnpfKey, variablesMap.get(field)) : formula(groupsModel, variablesMap);
                Object formValue = form;
                String symbol = groupsModel.getSymbol();
                boolean include = ("like".equals(symbol) || "notLike".equals(symbol));
                if ("<>".equals(symbol)) {
                    symbol = "!=";
                }
                int fieldValueType = groupsModel.getFieldValueType();
                String valueJnpfKey = StringUtil.isNotEmpty(groupsModel.getFieldValueJnpfKey()) ? groupsModel.getFieldValueJnpfKey() : jnpfKey;
                Object filedData = groupsModel.getFieldValue();
                Object value = fieldValueType == 2 ? filedValue(conditionModel, filedData, valueJnpfKey, form) : filedData(conditionModel, filedData, valueJnpfKey, form);
                Object fieldValue = value;
                String pression = formValue + symbol + fieldValue;
                if (include) {
                    if ("notLike".equals(symbol)) {
                        contain = "==-1";
                    }
                    symbol = ".indexOf";
                    formValue = formValue == null ? "''" : formValue;
                    pression = formValue + ".toString()" + symbol + "(" + fieldValue + ")" + contain;
                }
                expression.append(pression);
                if (!StringUtils.isEmpty(logic) && i != groups.size() - 1) {
                    expression.append(" " + search(logic) + " ");
                }
            }
            expression.append(")");
            expressionAll.add(expression.toString());
        }
        for (int i = 0; i < expressionAll.size(); i++) {
            String script = expressionAll.get(i);
            String search = i != expressionAll.size() - 1 ? search(matchLogic) : "";
            condition.append(script + " " + search + " ");
        }


        try {
            flag = (Boolean) scriptEngine.eval(condition.toString());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return flag;
    }



    @Override
    public List<FlowCandidateUserModel> candidateUser(String id, FlowModel flowModel) throws WorkFlowException {
        List<FlowCandidateUserModel> dataList = new ArrayList<>();
        String flowId = flowModel.getFlowId();
        Map<String, Object> formData = flowModel.getFormData();
        String nodeCode = flowModel.getNodeCode();
        FlowTemplateAllModel model = flowTaskUtil.templateJsonNoLongText(flowModel.getFlowId());
        String processDefinitionId = model.getTemplateJson().getProcessDefinitionId();
        Process bpmnModelMainProcess = getBpmnModelMainProcess(processDefinitionId);
        String attributeValueByTaskDefinitionKey = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, nodeCode, "");
        Properties properties = JSONObject.parseObject(attributeValueByTaskDefinitionKey, new TypeReference<Properties>() {
        });
        List<String> list = new ArrayList<>();
        list.addAll(properties.getApprovers());
        list.addAll(properties.getInitiator());
        List<String> userId = serviceUtil.getUserListAll(list);
        Pagination pagination = JsonUtil.getJsonToBean(flowModel, Pagination.class);
        List<UserEntity> userName = serviceUtil.getUserName(userId, pagination);
        flowModel.setTotal(pagination.getTotal());
        List<String> userIdAll = userName.stream().map(UserEntity::getId).collect(Collectors.toList());
        Map<String, List<UserRelationEntity>> userMap = serviceUtil.getListByUserIdAll(userIdAll).stream().filter(t -> PermissionConst.ORGANIZE.equals(t.getObjectType())).collect(Collectors.groupingBy(UserRelationEntity::getUserId));
        for (UserEntity entity : userName) {
            List<UserRelationEntity> listByUserId = userMap.get(entity.getId()) != null ? userMap.get(entity.getId()) : new ArrayList<>();
            StringJoiner joiner = new StringJoiner(",");
            for (UserRelationEntity relation : listByUserId) {
                List<OrganizeEntity> organizeId = serviceUtil.getOrganizeId(relation.getObjectId());
                if (organizeId.size() > 0) {
                    String organizeName = organizeId.stream().map(OrganizeEntity::getFullName).collect(Collectors.joining("/"));
                    joiner.add(organizeName);
                }
            }
            FlowCandidateUserModel userModel = JsonUtil.getJsonToBean(entity, FlowCandidateUserModel.class);
            userModel.setFullName(entity.getRealName() + "/" + entity.getAccount());
            userModel.setHeadIcon(UploaderUtil.uploaderImg(entity.getHeadIcon()));
            userModel.setOrganize(joiner.toString());
            dataList.add(userModel);
        }

        return dataList;
    }

    @Override
    @DSTransactional
    public void batch(FlowModel flowModel) throws WorkFlowException {
        List<String> idList = flowModel.getIds();
        Integer batchType = flowModel.getBatchType();
        UserInfo userInfo = flowModel.getUserInfo();
        for (String id : idList) {
            LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
            operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,id);
            operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
            FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
            FlowTaskEntity task = new FlowTaskEntity();


            FlowModel model = JsonUtil.getJsonToBean(flowModel, FlowModel.class);
            model.setId(id);
            switch (batchType) {
                case 0:
                    model.setVoluntarily(true);
                    auditAll(task,operator,model);
                    break;
                case 1:
                    rejectAll(task, operator, flowModel);
                    break;
                case 2:
                    flowModel.setFreeApproverUserId(flowModel.getFreeApproverUserId());
                    flowModel.setId(id);
                    transfer(flowModel);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public FlowCandidateVO batchCandidates(String flowId, String taskOperatorId, FlowModel flowModel) throws WorkFlowException {
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(flowId);
        FlowTemplateJsonEntity templateJson = templateAllModel.getTemplateJson();
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(taskOperatorId);
        FlowTaskNodeEntity taskNode = flowTaskNodeService.getInfo(operator.getTaskNodeId(), FlowTaskNodeEntity::getNodeNext, FlowTaskNodeEntity::getId);
        ChildNode childNodeAll = JsonUtil.getJsonToBean(templateJson.getFlowTemplateJson(), ChildNode.class);
        //获取流程节点
        List<ChildNodeList> nodeListAll = new ArrayList<>();
        List<ConditionList> conditionListAll = new ArrayList<>();
        //递归获取条件数据和节点数据
        FlowJsonUtil.getTemplateAll(childNodeAll, nodeListAll, conditionListAll);
        //判断节点是否有在条件中
        boolean isCondition = conditionListAll.stream().filter(t -> operator.getNodeCode().equals(t.getPrevId())).count() > 0;
        List<ChildNodeList> freeApprover = new ArrayList<>();
        List<ChildNodeList> branchFlow = new ArrayList<>();
        if (isCondition) {
            List<String> nodeNext = StringUtil.isNotEmpty(taskNode.getNodeNext()) ? Arrays.asList(taskNode.getNodeNext().split(",")) : new ArrayList<>();
            List<ChildNodeList> nextList = nodeListAll.stream().filter(t -> nodeNext.contains(t.getCustom().getNodeId())).collect(Collectors.toList());
            nextList.stream().forEach(t -> {
                if (FlowTaskOperatorEnum.Candidate.getCode().equals(t.getProperties().getAssigneeType())) {
                    freeApprover.add(t);
                }
                if (t.getCustom().getBranchFlow()) {
                    branchFlow.add(t);
                }
            });
        }
        if (freeApprover.size() > 0) {
            throw new WorkFlowException("条件流程包含候选人无法批量通过！");
        }
        if (branchFlow.size() > 0) {
            throw new WorkFlowException("下一节点为选择分支无法批量审批!");
        }
        return candidates(taskOperatorId, flowModel, true);
    }

    @Override
    public void permissions(String userId, FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, String msg, FlowModel flowModel) throws WorkFlowException {
        UserInfo userInfo = flowModel.getUserInfo();
        if (operator == null || FlowNodeEnum.Futility.getCode().equals(operator.getState())) {
            throw new WorkFlowException(StringUtil.isEmpty(msg) ? "" : msg);
        }
        List<String> flowDelegateList = flowDelegateService.getUser(userId, flowTask.getTemplateId(), userInfo.getUserId()).stream().map(FlowDelegateEntity::getToUserId).collect(Collectors.toList());
        flowDelegateList.add(userId);
        if (!flowDelegateList.contains(userInfo.getUserId())) {
            throw new WorkFlowException("没有权限操作");
        }
        if (FlowTaskStatusEnum.Cancel.getCode().equals(flowTask.getStatus())) {
            throw new WorkFlowException("该流程工单已终止");
        }
        if (FlowTaskStatusEnum.Revoke.getCode().equals(flowTask.getStatus())) {
            throw new WorkFlowException("该流程工单已撤回");
        }
    }

    @Override
    @DSTransactional
    public void change(FlowModel flowModel) throws WorkFlowException {
        Boolean resurgence = flowModel.getResurgence();
        if (resurgence) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(flowModel.getTaskId()).includeProcessVariables().singleResult();
            Process bpmnModelMainProcess = getBpmnModelMainProcess(historicProcessInstance.getProcessDefinitionId());
            UserTask firstNode = getFirstNode(bpmnModelMainProcess);
            String property = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, firstNode.getId(), "");
            Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
            });
            Boolean hasRestartBtn = properties.getHasRestartBtn();
            UserInfo userInfo = userProvider.get();
            FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
            operatorRecord.setNodeCode(BasicActivitiConstants.endEventId);
            operatorRecord.setNodeName("流程结束");
            operatorRecord.setHandleId(userInfo.getUserId());
            operatorRecord.setReceiveTime(new Date());
            operatorRecord.setOperatorId(userInfo.getUserId());
            operatorRecord.setTaskId(flowModel.getTaskId());
            operatorRecord.setId(RandomUtil.uuId());
            operatorRecord.setHandleStatus(FlowRecordEnum.resurrection.getCode());
            operatorRecord.setHandleTime(new Date());
            operatorRecord.setHandleOpinion(flowModel.getHandleOpinion());
            operatorRecord.setSignImg(flowModel.getSignImg());
            operatorRecord.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
            flowTaskOperatorRecordService.save(operatorRecord);


            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
            Map<String, Object> usedProcessVars = new HashMap<>();
            Set<String> keys = processVariables.keySet();
            Iterator<String> iterator = keys.iterator();
            while (iterator.hasNext()) {
                String next = iterator.next();
                if (next.contains("assigneeList")) {
                    iterator.remove();
                }
            }
            for (String key : keys) {
                usedProcessVars.put(key, processVariables.get(key));
            }

            //删除流程实例
            managementService.executeCommand(new RemoveProcCmd(historicProcessInstance.getId()));
            usedProcessVars.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());
            usedProcessVars.put(RERUN_TIME, new Date().getTime());
            Authentication.setAuthenticatedUserId(flowModel.getTrueAssignee());
            Map<String, Object> variablesMap = new HashMap<>();
            variablesMap.put("tempRestart", true);
            String nodeCode = flowModel.getTaskNodeId();
            if (firstNode.getId().equals(nodeCode)) {
                variablesMap.put("tempFirstFlag", true);
            }
            runtimeService.createProcessInstanceBuilder()
                    .predefineProcessInstanceId(flowModel.getTaskId())
                    .processDefinitionId(historicProcessInstance.getProcessDefinitionId())
                    .businessKey(historicProcessInstance.getBusinessKey())
                    .name(historicProcessInstance.getName())
                    .variables(usedProcessVars)
                    .transientVariables(variablesMap)
                    .start();
            //
            if (!firstNode.getId().equals(nodeCode)) {
                List<String> activeActivityIds = runtimeService.getActiveActivityIds(historicProcessInstance.getId());
                runtimeService.createChangeActivityStateBuilder()
                        .processInstanceId(historicProcessInstance.getId())
                        .moveActivityIdsToSingleActivityId(activeActivityIds, nodeCode)
                        .changeState();
            }
            return;

        }
        String nodeCode = flowModel.getTaskNodeId();
            List<String> activeActivityIds = runtimeService.getActiveActivityIds(flowModel.getTaskId());
            ArrayList<String> distinct = CollUtil.distinct(activeActivityIds);
            String currentNode = activeActivityIds.get(0);
            HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().processInstanceId(flowModel.getTaskId())
                    .activityId(currentNode).unfinished().listPage(0, 1).get(0);
            FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
            operatorRecord.setNodeCode(historicActivityInstance.getActivityId());
            operatorRecord.setNodeName(historicActivityInstance.getActivityName());
            operatorRecord.setHandleId(historicActivityInstance.getAssignee());
            operatorRecord.setReceiveTime(new Date());
            operatorRecord.setOperatorId(historicActivityInstance.getAssignee());
            operatorRecord.setTaskId(historicActivityInstance.getProcessInstanceId());
            operatorRecord.setId(RandomUtil.uuId());
            operatorRecord.setHandleStatus(FlowRecordEnum.change.getCode());
            operatorRecord.setHandleTime(new Date());
            operatorRecord.setHandleOpinion(flowModel.getHandleOpinion());
            operatorRecord.setSignImg(flowModel.getSignImg());
            operatorRecord.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
            flowTaskOperatorRecordService.save(operatorRecord);

            List<String> mainExecutions = getMainExecutions(flowModel.getTaskId());
            runtimeService.createChangeActivityStateBuilder()
                    .processInstanceId(flowModel.getTaskId())
                    .moveExecutionsToSingleActivityId(mainExecutions,nodeCode)
                    .changeState();

    }
    private List<String> getPreviousNode(FlowNode node,List<String> rejectNodeCollection,List<HistoricActivityInstance> list) {
        List<SequenceFlow> incomingFlows = node.getIncomingFlows();
        for (SequenceFlow incomingFlow : incomingFlows) {
            FlowElement sourceFlowElement = incomingFlow.getSourceFlowElement();
            if(sourceFlowElement instanceof UserTask){
                List<String>  finishedNodeIdList = new ArrayList<>();
                for (HistoricActivityInstance historicActivityInstance : list) {
                    finishedNodeIdList.add(historicActivityInstance.getActivityId());
                }
                if(finishedNodeIdList.contains(sourceFlowElement.getId())){
                    rejectNodeCollection.add(sourceFlowElement.getId());
                }
            }
            else if(sourceFlowElement instanceof ParallelGateway || sourceFlowElement instanceof InclusiveGateway){
                getPreviousNode((FlowNode) sourceFlowElement,rejectNodeCollection,list);
            }
            else if(sourceFlowElement instanceof ExclusiveGateway){
                List<String> activiyIds= new ArrayList<>();
                if(sourceFlowElement.getId().endsWith("_end")){
                    List<String> previousNodes = getPreviousNode((FlowNode) sourceFlowElement, rejectNodeCollection, list);
                    activiyIds.addAll(previousNodes);
                    String nodeId="";
                    for (HistoricActivityInstance historicActivityInstance : list) {
                        if(activiyIds.contains(historicActivityInstance.getActivityId())){
                            nodeId=historicActivityInstance.getActivityId();
                        }
                    }
                    //
                    rejectNodeCollection.removeAll(activiyIds);
                    rejectNodeCollection.add(nodeId);
                }
                else{
                    getPreviousNode((FlowNode) sourceFlowElement,rejectNodeCollection,list);
                }
            }

        }
        return rejectNodeCollection;
    }

    @Override
    public FlowRejectVO rejectList(String id, boolean batch) throws WorkFlowException {
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(id).singleResult();
        Process process = getBpmnModelMainProcess(task.getProcessDefinitionId());
        String property = getAttributeValueByTaskDefinitionKey(process, task.getTaskDefinitionKey(), "userTask");
        Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
        });
        Integer rejectType = properties.getRejectType();
        String rejectStep = properties.getRejectStep();
        /**
         * rejectStep 有几种情况
         *
         * 流程发起
         * 上级审批节点
         * 自选审批节点
         * 具体的一个节点id
         */


        Collection<FlowElement> flowElements = process.getFlowElements();
        List<FlowElement> elementList = getAllElementsWithNoUsed(process);
        FlowRejectVO flowRejectVO = new FlowRejectVO();
        //
//        flowRejectVO.setIsLastAppro(false);
//        if(.equals(rejectType)){
//            flowRejectVO.setIsLastAppro(true);
//        }
        List<TaskNodeModel> taskNodeModels = new ArrayList<TaskNodeModel>();
//        if(FlowNature.RestartType.equals(rejectType)){
        if(FlowNature.UP.equals(rejectStep)){
            UserTask userTaskNode = (UserTask) process.getFlowElement(task.getTaskDefinitionKey());
            List<String> rejectNodeCollection= new ArrayList<>();
            List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).finished().orderByHistoricActivityInstanceEndTime().activityType("userTask").desc().list();
            List<String> rejectNodeIds = getPreviousNode(userTaskNode,rejectNodeCollection,list);
            for (String rejectNodeId : rejectNodeIds) {
                TaskNodeModel taskNodeModel = new TaskNodeModel();
                FlowElement flowElement = process.getFlowElement(rejectNodeId);
                taskNodeModel.setId(flowElement.getId());
                taskNodeModel.setNodeName(flowElement.getName());
                taskNodeModel.setNodeCode(flowElement.getId());
                taskNodeModels.add(taskNodeModel);
            }
            flowRejectVO.setList(taskNodeModels);
            return flowRejectVO;
        }
        else if(FlowNature.START.equals(rejectStep)){
            TaskNodeModel taskNodeModel = new TaskNodeModel();
            UserTask firstNode = getFirstNode(process);
            taskNodeModel.setId(firstNode.getId());
            taskNodeModel.setNodeName(firstNode.getName());
            taskNodeModel.setNodeCode(firstNode.getId());
            taskNodeModels.add(taskNodeModel);
            flowRejectVO.setList(taskNodeModels);
            return flowRejectVO;
        }
        else if(FlowNature.Reject.equals(rejectStep)){
            flowRejectVO.setIsLastAppro(true);
            for (FlowElement flowElement : elementList) {
                if(flowElement instanceof EndEvent){
                    TaskNodeModel taskNodeModel = new TaskNodeModel();
                    taskNodeModel.setId(flowElement.getId());
                    taskNodeModel.setNodeName("结束");
                    taskNodeModel.setNodeCode(flowElement.getId());
                    taskNodeModels.add(taskNodeModel);
                }
                else{
                    TaskNodeModel taskNodeModel = new TaskNodeModel();
                    taskNodeModel.setId(flowElement.getId());
                    taskNodeModel.setNodeName(flowElement.getName());
                    taskNodeModel.setNodeCode(flowElement.getId());
                    taskNodeModels.add(taskNodeModel);
                }
            }
            flowRejectVO.setList(taskNodeModels);
            return flowRejectVO;
        }
        //具体的nodeId
        else{
            TaskNodeModel taskNodeModel = new TaskNodeModel();
            FlowElement flowElement = process.getFlowElement(rejectStep);
            taskNodeModel.setId(flowElement.getId());
            taskNodeModel.setNodeName(flowElement.getName());
            taskNodeModel.setNodeCode(flowElement.getId());
            taskNodeModels.add(taskNodeModel);
            flowRejectVO.setList(taskNodeModels);
            return flowRejectVO;
        }
//        }





     /*   FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
        List<FlowTaskOperatorEntity> operatorList = flowTaskOperatorService.getList(operator.getTaskId()).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
        TaskNodeListModel taskNodeListModel = TaskNodeListModel.builder().id(operator.getTaskId()).state(FlowNodeEnum.Process.getCode()).build();
        List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeService.getList(taskNodeListModel,
                FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getNodePropertyJson,
                FlowTaskNodeEntity::getTaskId, FlowTaskNodeEntity::getNodeType,
                FlowTaskNodeEntity::getCompletion, FlowTaskNodeEntity::getCandidates,
                FlowTaskNodeEntity::getNodeCode, FlowTaskNodeEntity::getNodeNext,
                FlowTaskNodeEntity::getNodeName
        );
        //排除分支没有走过的节点
        FlowTaskNodeEntity nodeEntity = taskNodeList.stream().filter(t -> t.getId().equals(operator.getTaskNodeId())).findFirst().orElse(null);
        flowTaskUtil.nodeList(taskNodeList);
        ChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(), ChildNodeList.class);
        String rejectStep = childNodeList.getProperties().getRejectStep();
        List<FlowTaskNodeEntity> rejectNode = taskNodeList.stream().filter(t -> t.getNodeCode().equals(rejectStep)).collect(Collectors.toList());
        boolean up = FlowNature.UP.equals(rejectStep);
        boolean reject = FlowNature.Reject.equals(rejectStep);
        boolean start = FlowNature.START.equals(rejectStep);
        List<String> nodetype = ImmutableList.of(FlowNature.NodeSubFlow);
        if (rejectNode.size() == 0) {
            List<FlowTaskNodeEntity> taskNodeEntity = taskNodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).collect(Collectors.toList());
            if (up) {
                List<FlowTaskNodeEntity> collect = taskNodeList.stream().filter(t -> t.getNodeNext().contains(nodeEntity.getNodeCode())).collect(Collectors.toList());
                rejectNode.addAll(collect);
                List<FlowTaskNodeEntity> subFlowList = collect.stream().filter(t -> nodetype.contains(t.getNodeType())).collect(Collectors.toList());
                if (subFlowList.size() > 0) {
                    throw new WorkFlowException("退回节点包含子流程，退回失败");
                }
            } else if (reject) {
                Set<FlowTaskNodeEntity> rejectNodeList = new HashSet<>();
                List<String> nodeIdList = ImmutableList.of(operator.getTaskNodeId());
                flowTaskUtil.upNodeList(taskNodeList, nodeIdList, rejectNodeList, null);
                rejectNode.addAll(rejectNodeList.stream().filter(t -> !nodetype.contains(t.getNodeType())).collect(Collectors.toSet()));
            } else if (start) {
                rejectNode.addAll(taskNodeEntity);
            }
        }
        if (rejectNode.size() == 0) {
            throw new WorkFlowException("当前节点未审批，不能退回");
        }
        Set<FlowTaskNodeEntity> rejectNodeAll = new HashSet<>();
        for (int i = 0; i < rejectNode.size(); i++) {
            FlowTaskNodeEntity taskNodeEntity = rejectNode.get(i);
            boolean add = operatorList.stream().filter(t -> t.getTaskNodeId().equals(taskNodeEntity.getId())).count() > 0;
            if (add || !reject) {
                rejectNodeAll.add(taskNodeEntity);
            }
        }
        if (reject) {
            List<FlowTaskNodeEntity> startNode = taskNodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).collect(Collectors.toList());
            rejectNodeAll.addAll(startNode);
        }
        Set<FlowTaskNodeEntity> rejectNodeList = new HashSet<>();
        if (up) {
            FlowTaskNodeEntity upNode = new FlowTaskNodeEntity();
            List<String> node = rejectNode.stream().map(FlowTaskNodeEntity::getNodeCode).collect(Collectors.toList());
            upNode.setNodeCode(String.join(",", node));
            upNode.setNodeName("上一审批");
            rejectNodeList.add(upNode);
        } else {
            rejectNodeList.addAll(rejectNodeAll);
        }
        List<TaskNodeModel> nodeList = JsonUtil.getJsonToList(rejectNodeList, TaskNodeModel.class);
        List<FlowTaskOperatorEntity> rejectOperatorList = operatorList.stream().filter(t -> t.getTaskNodeId().equals(operator.getTaskNodeId())).collect(Collectors.toList());
        rejectOperatorList.stream().forEach(t -> {
            if (t.getId().equals(id)) {
                t.setCompletion(FlowNature.RejectCompletion);
            }
        });
        FlowCountersignModel countersign = new FlowCountersignModel();
        countersign.setTaskNode(nodeEntity);
        countersign.setOperatorList(rejectOperatorList);
        boolean isCountersign = flowTaskUtil.isRejectCountersign(countersign);
        FlowRejectVO vo = new FlowRejectVO();
        vo.setList(nodeList);
        boolean appro = reject ? isCountersign ? true : false : true;
        vo.setIsLastAppro(appro);
        return vo;*/
    }

    @Override
    @DSTransactional
    public void suspend(String id, FlowModel flowModel, boolean isSuspend) {
        UserInfo userInfo = flowModel.getUserInfo();
        ActivityInstance activityInstance = runtimeService.createActivityInstanceQuery().unfinished().processInstanceId(id).listPage(0, 1).get(0);
        FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
        flowTaskOperatorRecordEntity.setNodeCode(activityInstance.getActivityId());
        flowTaskOperatorRecordEntity.setNodeName(activityInstance.getActivityName());
        flowTaskOperatorRecordEntity.setHandleId(userInfo.getUserId());
        Date date = new Date();
        flowTaskOperatorRecordEntity.setReceiveTime(date);
        flowTaskOperatorRecordEntity.setHandleTime(date);
        flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
        flowTaskOperatorRecordEntity.setOperatorId(userInfo.getUserId());
//        flowTaskOperatorRecordEntity.setTaskOperatorId();
        flowTaskOperatorRecordEntity.setTaskNodeId(activityInstance.getTaskId());
        flowTaskOperatorRecordEntity.setTaskId(activityInstance.getProcessInstanceId());
        flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
        flowTaskOperatorRecordEntity.setStatus(0);
        flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        flowTaskOperatorRecordEntity.setId(IdWorker.getIdStr());

        if(isSuspend){
            runtimeService.setVariable(id,PROCESS_STATUS,FlowTaskStatusEnum.Suspend.getCode());
            flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.suspend.getCode());
            runtimeService.suspendProcessInstanceById(id);
        }
        else{
            flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.restore.getCode());
            runtimeService.activateProcessInstanceById(id);
            runtimeService.setVariable(id,PROCESS_STATUS,FlowTaskStatusEnum.Handle.getCode());
        }
        flowTaskOperatorRecordService.save(flowTaskOperatorRecordEntity);
        //启动、停止定时器
//        workTimeoutJobUtil.suspendFuture(operatorList, isSuspend);
    }

    @Override
    @DSTransactional
    public void invoke(FlowModel flowModel) {
        String id = flowModel.getId();
        flowModel.setUserInfo(userProvider.get());

        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,id);
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity nativeOperator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        activitiUtils.validProcessStatus(nativeOperator.getTaskId());
        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,nativeOperator.getId());
        FlowTaskOperatorRecordEntity operatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);

        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(nativeOperator.getTaskNodeId()).includeProcessVariables().singleResult();
        taskService.delegateTask(task.getId(),flowModel.getFreeApproverUserId());
        Map<String, Object> processVariables = task.getProcessVariables();
        String templateJsonId = MapUtil.getStr(processVariables, FLOW_TEMPLATE_JSON_ID);
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(templateJsonId);

        //先判断B这个人 有没有 operrator  如果有 用之前的 ,如果没有 新增

        operatorEntityLambdaQueryWrapper.clear();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,id);
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,flowModel.getFreeApproverUserId());
        FlowTaskOperatorEntity transfterOperator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);

        //更新源的转办意见
        operatorRecordEntity.setHandleStatus(FlowRecordEnum.transfer.getCode());
        operatorRecordEntity.setHandleTime(new Date());
        operatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
        flowTaskOperatorRecordService.updateById(operatorRecordEntity);

        //
        if(transfterOperator==null){
            transfterOperator = new FlowTaskOperatorEntity();
            transfterOperator.setId(RandomUtil.uuId());
            transfterOperator.setHandleId(flowModel.getFreeApproverUserId());
            transfterOperator.setTaskNodeId(task.getId());
            transfterOperator.setTaskId(task.getProcessInstanceId());
            transfterOperator.setNodeCode(task.getTaskDefinitionKey());
            transfterOperator.setNodeName(task.getName());
            transfterOperator.setDescription(task.getDescription());
            transfterOperator.setCreatorTime(new Date());
            transfterOperator.setCompletion(FlowNature.ProcessCompletion);
            transfterOperator.setState(FlowNodeEnum.Process.getCode());
            flowTaskOperatorService.save(transfterOperator);

            FlowTaskOperatorRecordEntity transferFlowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
            transferFlowTaskOperatorRecordEntity.setNodeCode(task.getTaskDefinitionKey());
            transferFlowTaskOperatorRecordEntity.setNodeName(task.getName());
            transferFlowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.DOING.getCode());
            transferFlowTaskOperatorRecordEntity.setHandleId(flowModel.getFreeApproverUserId());
            Date date = new Date();
            transferFlowTaskOperatorRecordEntity.setReceiveTime(date);
            transferFlowTaskOperatorRecordEntity.setHandleTime(date);
            transferFlowTaskOperatorRecordEntity.setOperatorId(flowModel.getFreeApproverUserId());
            transferFlowTaskOperatorRecordEntity.setTaskOperatorId(transfterOperator.getId());
            transferFlowTaskOperatorRecordEntity.setTaskNodeId(task.getId());
            transferFlowTaskOperatorRecordEntity.setTaskId(task.getProcessInstanceId());
            transferFlowTaskOperatorRecordEntity.setId(RandomUtil.uuId());
            flowTaskOperatorRecordService.create(transferFlowTaskOperatorRecordEntity);
        }
        else{

        }
        Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
        String property = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, task.getTaskDefinitionKey(), "userTask");
        Properties properties = JSONObject.parseObject(property, new TypeReference<Properties>() {
        });
        //1.3调用通知
        Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
        MsgConfig approveMsgConfig = properties.getWaitMsgConfig();
        Integer msgConfigOnn = approveMsgConfig.getOn();

        Boolean messageFlag=false;
        if(msgConfigOnn!=0){
            if(msgConfigOnn==2){
                if(firstNodeProperty.getWaitMsgConfig().getOn()!=0){
                    messageFlag=true;
                }
            }
            else{
                messageFlag=true;
            }
        }

        if(messageFlag){
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            flowMsgModel.setCopy(Boolean.FALSE);

            flowMsgModel.setStartNodeProperties(firstNodeProperty);
            flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
            List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
            operatorEntityList.add(transfterOperator);
            flowMsgModel.setOperatorList(operatorEntityList);
            flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
            FlowTaskDTO flowTaskDTO = new FlowTaskDTO();

            flowTaskDTO.setCreatorUserId(MapUtil.getStr(processVariables,APPLY_USER_ID));
            flowTaskDTO.setStatus(MapUtil.getInt(processVariables,PROCESS_STATUS));
            flowTaskDTO.setFullName(MapUtil.getStr(processVariables,BUSINESS_TITLE));
            flowMsgModel.setTaskEntity(flowTaskDTO);

            FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
            flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
            flowTaskNodeDTO.setTaskNodeId(task.getId());
            flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);
            flowMsgModel.setFlowModel(flowModel);
            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
            flowMsgModel.setTaskId(task.getProcessInstanceId());
            flowMsgModel.setTaskNodeId(task.getId());
            flowMsgUtil.message(flowMsgModel);
        }
    }

    @Override
    @DSTransactional
    public void taskCancel(FlowTaskOperatorEntity operator, FlowModel flowModel) {
//        flowTaskOperatorService.update(taskOperator);
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(operator.getTaskNodeId()).includeProcessVariables().singleResult();
        activitiUtils.validProcessStatus(task.getProcessInstanceId());
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"");
        Map<String, Object> processVariables = task.getProcessVariables();
        String templateJsonId = MapUtil.getStr(processVariables, FLOW_TEMPLATE_JSON_ID);
        FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(templateJsonId);
        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId,operator.getTaskNodeId());
        lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getHandleId,UserProvider.getUser().getUserId());
        FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
//        flowTaskOperatorRecordEntity.setOperatorId(flowModel.getFreeApproverUserId());
//        flowTaskOperatorRecordEntity.setHandleId(flowModel.getFreeApproverUserId());
        flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.cancel.getCode());
        flowTaskOperatorRecordEntity.setHandleTime(new Date());
        flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
        flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
        flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);


    }

    @Override
    @DSTransactional
    public void multiAdd(FlowTaskOperatorEntity operator, FlowModel flowModel) {
//        flowTaskOperatorService.update(taskOperator);
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(operator.getTaskNodeId()).includeProcessVariables().singleResult();
        activitiUtils.validProcessStatus(task.getProcessInstanceId());
        String freeApproverUserId = flowModel.getFreeApproverUserId();
        //判断当前是 串行 并行还是或
        Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
        UserTask userTask = (UserTask) bpmnModelMainProcess.getFlowElement(task.getTaskDefinitionKey());
        boolean b = userTask.hasMultiInstanceLoopCharacteristics();
        Date date = new Date();
        if(b){
            MultiInstanceLoopCharacteristics loopCharacteristics = userTask.getLoopCharacteristics();
            if(StringUtils.isNotBlank(loopCharacteristics.getCompletionCondition())){
                if("${nrOfCompletedInstances/nrOfInstances > 0}".equals(loopCharacteristics.getCompletionCondition()))
                    throw new WorkFlowException("或签节点不允许加签");
            }
            if(userProvider.get().getUserId().equals(freeApproverUserId)){
                throw new WorkFlowException("自己不能加签给自己");
            }
            Map<String,Object> variableMap= new HashMap<>();
            variableMap.put("assignee",freeApproverUserId);
            boolean sequential = userTask.getLoopCharacteristics().isSequential();
            if(sequential){
                String executionId = task.getExecutionId();
                String taskDefinitionKey = task.getTaskDefinitionKey();
                String variableName = taskDefinitionKey + "assigneeList";
                List assigneeUserList = runtimeService.getVariable(executionId, variableName, List.class);
                assigneeUserList.add(freeApproverUserId);
                runtimeService.setVariable(executionId,variableName,assigneeUserList);
            }

            ExecutionEntity execution = (ExecutionEntity) runtimeService.addMultiInstanceExecution(userTask.getId(), task.getProcessInstanceId(), variableMap);

            org.flowable.task.api.Task addMultiTask = taskService.createTaskQuery().executionId(execution.getId()).singleResult();
            FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
            flowTaskOperatorRecordEntity.setNodeCode(task.getTaskDefinitionKey());
            flowTaskOperatorRecordEntity.setNodeName(task.getName());
            flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.copyId.getCode());
            String userId = flowModel.getUserInfo().getUserId();
            flowTaskOperatorRecordEntity.setHandleId(userId);
            flowTaskOperatorRecordEntity.setReceiveTime(date);
            flowTaskOperatorRecordEntity.setHandleTime(date);
            flowTaskOperatorRecordEntity.setOperatorId(userId);
//            flowTaskOperatorRecordEntity.setTaskNodeId(task.getId());
            flowTaskOperatorRecordEntity.setTaskId(task.getProcessInstanceId());
            flowTaskOperatorRecordEntity.setId(RandomUtil.uuId());
            flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
            flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
            flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
            flowTaskOperatorRecordService.save(flowTaskOperatorRecordEntity);
        }




    }


    @Override
    @DSTransactional
    public void cc(FlowTaskOperatorEntity operator, FlowModel flowModel) {
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(operator.getTaskNodeId()).includeProcessVariables().singleResult();
        activitiUtils.validProcessStatus(task.getProcessInstanceId());
        String freeApproverUserId = flowModel.getFreeApproverUserId();
        FlowTaskCirculateEntity circulate = new FlowTaskCirculateEntity();
        circulate.setId(RandomUtil.uuId());
        circulate.setObjectId(freeApproverUserId);
        circulate.setNodeCode(task.getTaskDefinitionKey());
        circulate.setNodeName(task.getName());
        circulate.setTaskNodeId(task.getId());
        circulate.setTaskId(task.getProcessInstanceId());
        Map<String, Object> map = task.getProcessVariables();
        String applyUserID = MapUtil.getStr(map, APPLY_USER_ID);
        UserEntity userEntity = userService.getInfo(applyUserID);
        circulate.setEnCode(MapUtil.getStr(map,BILL_CODE));
        circulate.setFullName(MapUtil.getStr(map,BUSINESS_TITLE));
        circulate.setTemplateId(MapUtil.getStr(map,FLOW_ENGINE_ID));
        circulate.setFlowId(MapUtil.getStr(map,FLOW_TEMPLATE_JSON_ID));
        circulate.setFlowCategory(MapUtil.getStr(map,PROCESS_CATEGORY));
        circulate.setFlowUrgent(MapUtil.getInt(map,FLOW_URGENT));
        circulate.setCreatorTime(new Date());
        circulate.setApplyUserId(userEntity.getRealName()+"/"+userEntity.getAccount());
        circulate.setApplyUserIdReal(userEntity.getId());
        circulate.setProcessStatus(MapUtil.getInt(map,PROCESS_STATUS));
        flowTaskCirculateService.save(circulate);

        ArrayList<FlowTaskCirculateEntity> flowTaskCirculateEntities = CollUtil.newArrayList(circulate);

        //1.3调用通知
        Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
        String taskProperty = getAttributeValueByTaskDefinitionKey(bpmnModelMainProcess, task.getTaskDefinitionKey(), "userTask");
        Properties properties = JSONObject.parseObject(taskProperty, new TypeReference<Properties>() {
        });

        MsgConfig copyMsgConfig = properties.getCopyMsgConfig();
        Integer on = copyMsgConfig.getOn();
        Boolean messageFlag=false;
        if(on!=0){
            messageFlag=true;
        }
        if(messageFlag){
            FlowMsgModel flowMsgModel = new FlowMsgModel();
            if(CollUtil.isNotEmpty(flowTaskCirculateEntities)){
                flowMsgModel.setCirculateList(flowTaskCirculateEntities);
                flowMsgModel.setCopy(Boolean.TRUE);
            }
            flowMsgModel.setWait(Boolean.FALSE);
            Properties firstNodeProperty = getFirstNodeProperty(task.getProcessDefinitionId());
            flowMsgModel.setStartNodeProperties(firstNodeProperty);
            flowMsgModel.setCurrentNodeProperties(properties);
//                    flowMsgModel.setNodeList(taskNodeList);
            List<FlowTaskOperatorEntity> operatorEntityList = new ArrayList<>();
            LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,task.getId());
            FlowTaskOperatorEntity operatorServiceOne = flowTaskOperatorService.getOne(lambdaQueryWrapper);
            operatorEntityList.add(operatorServiceOne);
            flowMsgModel.setOperatorList(operatorEntityList);
            flowMsgModel.setData(flowModel.getFormData());
//                    flowMsgModel.setFlowModel(flowModel);
            FlowTaskDTO flowTask = new FlowTaskDTO();
            flowTask.setCreatorUserId(flowModel.getTrueAssignee());
            flowTask.setStatus( FlowTaskStatusEnum.Handle.getCode());
            flowTask.setFullName(MapUtil.getStr(map,BUSINESS_TITLE));
            flowMsgModel.setTaskEntity(flowTask);

            FlowTaskNodeDTO flowTaskNodeDTO = new FlowTaskNodeDTO();
            flowTaskNodeDTO.setTaskId(task.getProcessInstanceId());
            flowTaskNodeDTO.setTaskNodeId(task.getId());
            flowMsgModel.setTaskNodeEntity(flowTaskNodeDTO);

            flowModel.setUserInfo(UserProvider.getUser());
            flowMsgModel.setFlowModel(flowModel);
            FlowTemplateAllModel templateAllModel = flowTaskUtil.templateJson(MapUtil.getStr(map, FLOW_TEMPLATE_JSON_ID));
//                    flowMsgModel.setUserInfo(UserProvider.getUser());
            flowMsgModel.setFlowTemplateAllModel(templateAllModel);
            flowMsgModel.setTaskId(task.getProcessInstanceId());
            flowMsgModel.setTaskNodeId(task.getId());
            flowMsgUtil.message(flowMsgModel);
        }
    }

    @Override
    @DSTransactional
    public void counterSignAbstention(List<String> idList, FlowModel flowModel) {

        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,idList.get(0));
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        flowModel.setUserInfo(userInfo);
        activitiUtils.validProcessStatus(operator.getTaskId());

        //
        String taskNodeId = operator.getTaskNodeId();
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(taskNodeId).singleResult();
        String executionId = managementService.executeCommand(new GetSecondExecutionIdCmd(task.getExecutionId()));
        Map<String, Object> variables = runtimeService.getVariables(executionId);
        Integer rejectNum = MapUtil.getInt(variables, RootExecutionVariableConstants.MULTI_INSTANCE_NUM_ABSTENTION);
        if(rejectNum==null){
            runtimeService.setVariable(executionId,RootExecutionVariableConstants.MULTI_INSTANCE_NUM_ABSTENTION,1);
        }
        else{
            rejectNum=rejectNum+1;
            runtimeService.setVariable(executionId,RootExecutionVariableConstants.MULTI_INSTANCE_NUM_ABSTENTION,rejectNum);
        }

        LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,operator.getId());
        FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
        flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.counterSignAbstention.getCode());
        flowTaskOperatorRecordEntity.setHandleTime(new Date());
        flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
        flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
        flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
        flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);

        taskService.complete(task.getId());


    }

    @Override
    @DSTransactional
    public Integer lockUnLock(List<String> idList, FlowModel flowModel) {

        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,idList.get(0));
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        flowModel.setUserInfo(userInfo);


        //
        String taskNodeId = operator.getTaskNodeId();
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(taskNodeId).singleResult();
        boolean exists = redisUtil.exists(LOCK_STR + task.getProcessInstanceId());
        if(exists){
            redisUtil.remove(LOCK_STR +task.getProcessInstanceId());
            LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,operator.getId());
            FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
            flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.DOING.getCode());
            flowTaskOperatorRecordEntity.setHandleTime(new Date());
            flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
            flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
            flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
            flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);
            return 1;
        }
        else{
            redisUtil.insert(LOCK_STR +task.getProcessInstanceId(),true);
            LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskOperatorId,operator.getId());
            FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
            flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.lock.getCode());
            flowTaskOperatorRecordEntity.setHandleTime(new Date());
            flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
            flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
            flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
            flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);
            return 2;
        }
    }

    @Override
    @DSTransactional
    public void assist(String id, FlowModel flowModel) {

        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,id);
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        flowModel.setUserInfo(userInfo);
        activitiUtils.validProcessStatus(operator.getTaskId());

        //
        String taskNodeId = operator.getTaskNodeId();
        org.flowable.task.api.Task mainTask = taskService.createTaskQuery().taskId(taskNodeId).singleResult();

        Date date = new Date();

        FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
        flowTaskOperatorRecordEntity.setNodeCode(mainTask.getTaskDefinitionKey());
        flowTaskOperatorRecordEntity.setNodeName(mainTask.getName());
        flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.assist.getCode());
        flowTaskOperatorRecordEntity.setHandleId(userInfo.getUserId());
        flowTaskOperatorRecordEntity.setReceiveTime(date);
        flowTaskOperatorRecordEntity.setHandleTime(date);
//        flowTaskOperatorRecordEntity.setHandleOpinion();
        flowTaskOperatorRecordEntity.setOperatorId(userInfo.getUserId());
//        flowTaskOperatorRecordEntity.setTaskOperatorId();
//        flowTaskOperatorRecordEntity.setTaskNodeId();
        flowTaskOperatorRecordEntity.setTaskId(mainTask.getProcessInstanceId());
//        flowTaskOperatorRecordEntity.setSignImg();
        flowTaskOperatorRecordEntity.setStatus(0);
//        flowTaskOperatorRecordEntity.setFileList();
//        flowTaskOperatorRecordEntity.setDraftData();
//        flowTaskOperatorRecordEntity.setApproverType();
//        flowTaskOperatorRecordEntity.setSortCode();
//        flowTaskOperatorRecordEntity.setDeleteMark();
//        flowTaskOperatorRecordEntity.setDeleteTime();
//        flowTaskOperatorRecordEntity.setDeleteUserId();
//        flowTaskOperatorRecordEntity.setLastModifyTime();
//        flowTaskOperatorRecordEntity.setLastModifyUserId();
//        flowTaskOperatorRecordEntity.setCreatorTime();
//        flowTaskOperatorRecordEntity.setCreatorUserId();
//        flowTaskOperatorRecordEntity.setTenantId();
        flowTaskOperatorRecordService.save(flowTaskOperatorRecordEntity);




        //1.生成子任务
        TaskEntity task = (TaskEntity) taskService.newTask(IdWorker.getIdStr());
            task.setCategory(mainTask.getCategory());
            task.setDescription(mainTask.getDescription());
            task.setTenantId(mainTask.getTenantId());
            task.setAssignee(flowModel.getFreeApproverUserId());
            task.setName(mainTask.getName());
            task.setParentTaskId(mainTask.getId());
            task.setProcessDefinitionId(mainTask.getProcessDefinitionId());
            task.setProcessInstanceId(mainTask.getProcessInstanceId());
            task.setTaskDefinitionKey(mainTask.getTaskDefinitionKey());
//            task.setTaskDefinitionId(ptask.getTaskDefinitionId());
            task.setFormKey(mainTask.getFormKey());
            task.setPriority(mainTask.getPriority());
            task.setCreateTime(new Date());
            taskService.saveTask(task);

    }

    @Override
    @DSTransactional
    public void freeApprover(AddMultiFlowModel flowModel) {
        boolean before = FlowNature.Before.equals(flowModel.getFreeApproverType());
//        flowModel.setParentId(isUser ? operator.getId() : flowModel.getParentId());
//        flowModel.setRollbackId(before ? operator.getId() : operator.getRollbackId());
        //
        Integer nodeFlag = flowModel.getNodeFlag();
        LambdaQueryWrapper<FlowTaskOperatorEntity> operatorEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //原本通过taskNodeId 也就是任务id可以唯一定位 此条数据, 因为有委派业务,所以1个任务id可能有多个
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,flowModel.getId());
        UserInfo userInfo = userProvider.get();
        operatorEntityLambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,userInfo.getUserId());
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getOne(operatorEntityLambdaQueryWrapper);
        flowModel.setUserInfo(userInfo);
        org.flowable.task.api.Task task = taskService.createTaskQuery().taskId(operator.getTaskNodeId()).singleResult();
        activitiUtils.validProcessStatus(task.getProcessInstanceId());


        boolean isUser = ObjectUtil.isNotEmpty(flowModel.getFreeApproverUserId());
        String freeApproverUserId = flowModel.getFreeApproverUserId().toString();
        //判断当前是 串行 并行还是或
        Process bpmnModelMainProcess = getBpmnModelMainProcess(task.getProcessDefinitionId());
        UserTask userTask = (UserTask) bpmnModelMainProcess.getFlowElement(task.getTaskDefinitionKey());
        boolean b = userTask.hasMultiInstanceLoopCharacteristics();
        if(b){
            MultiInstanceLoopCharacteristics loopCharacteristics = userTask.getLoopCharacteristics();
            if(StringUtils.isNotBlank(loopCharacteristics.getCompletionCondition())){
                if(HQ_COUNTERSIGN_COMPLETE_CONDITION.equals(loopCharacteristics.getCompletionCondition()) && !before){
                    throw new WorkFlowException("或签节点不需要进行后加签!");
                }

            }
//                if(userProvider.get().getUserId().equals(freeApproverUserId)){
//                    throw new WorkFlowException("自己不能加签给自己");
//                }
            Map<String,Object> variableMap= new HashMap<>();
            variableMap.put("assignee",freeApproverUserId);
            boolean sequential = userTask.getLoopCharacteristics().isSequential();
            if(sequential){
                String executionId = task.getExecutionId();
                String taskDefinitionKey = task.getTaskDefinitionKey();
                String variableName = taskDefinitionKey + "assigneeList";
                List assigneeUserList = runtimeService.getVariable(executionId, variableName, List.class);
                assigneeUserList.add(freeApproverUserId);
                runtimeService.setVariable(executionId,variableName,assigneeUserList);
                FlowModel addMultiModel = new FlowModel();
                addMultiModel.setParentId(isUser ? operator.getId() : flowModel.getParentId());
                addMultiModel.setRollbackId(before ? operator.getId() : operator.getRollbackId());
                FlowContextHolder.addFlowModel(addMultiModel);
                //防止拿出来再改
            }
            ExecutionEntity execution = (ExecutionEntity) runtimeService.addMultiInstanceExecution(userTask.getId(), task.getProcessInstanceId(), variableMap);
            org.flowable.task.api.Task addMultiTask = taskService.createTaskQuery().executionId(execution.getId()).singleResult();
            List<String> taskNodeIds=new ArrayList<>();
            taskNodeIds.add(task.getId());
            FlowTaskOperatorRecordEntity mainOperator=null;
            if(addMultiTask!=null){
                taskNodeIds.add(addMultiTask.getId());

                LambdaQueryWrapper<FlowTaskOperatorEntity> lambdaQueryWrapper =new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getTaskNodeId,addMultiTask.getId());
                lambdaQueryWrapper.eq(FlowTaskOperatorEntity::getHandleId,freeApproverUserId);
                FlowTaskOperatorEntity addMultiTaskOperatorEntity = flowTaskOperatorService.getOne(lambdaQueryWrapper);

                LambdaQueryWrapper<FlowTaskOperatorRecordEntity> flowTaskOperatorRecordEntityLambdaQueryWrapper= new LambdaQueryWrapper<>();
                flowTaskOperatorRecordEntityLambdaQueryWrapper.in(FlowTaskOperatorRecordEntity::getTaskNodeId,taskNodeIds);
                List<FlowTaskOperatorRecordEntity> list = flowTaskOperatorRecordService.list(flowTaskOperatorRecordEntityLambdaQueryWrapper);
                FlowTaskOperatorRecordEntity addFlowTaskOperatorRecordEntity=null;
                for (FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity : list) {
                    if(flowTaskOperatorRecordEntity.getTaskNodeId().equals(addMultiTask.getId())){
                        addFlowTaskOperatorRecordEntity=flowTaskOperatorRecordEntity;
                    }
                    if(flowTaskOperatorRecordEntity.getTaskNodeId().equals(task.getId())){
                        mainOperator=flowTaskOperatorRecordEntity;
                        mainOperator.setHandleOpinion(flowModel.getHandleOpinion());
                        mainOperator.setSignImg(flowModel.getSignImg());
                        mainOperator.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
                    }
                }

                if(before){
                    managementService.executeCommand(new SuspendTaskCmd(task.getId()));
                    mainOperator.setHandleStatus(FlowRecordEnum.befoCopyId.getCode());
                }
                else{
                    taskService.complete(task.getId());
                    mainOperator.setHandleStatus(FlowRecordEnum.copyId.getCode());
                }
                addMultiTaskOperatorEntity.setParentId(isUser ? operator.getId() : flowModel.getParentId());
                addMultiTaskOperatorEntity.setRollbackId(before ? operator.getId() : operator.getRollbackId());
                flowTaskOperatorService.updateById(addMultiTaskOperatorEntity);



                List<FlowTaskOperatorRecordEntity> flowTaskOperatorRecordEntities= new ArrayList<>();
                flowTaskOperatorRecordEntities.add(addFlowTaskOperatorRecordEntity);
                flowTaskOperatorRecordEntities.add(mainOperator);
                flowTaskOperatorRecordService.updateBatchById(flowTaskOperatorRecordEntities);
            }
            //串行会签可能是null
            else{
                LambdaQueryWrapper<FlowTaskOperatorRecordEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskNodeId,task.getId());
                FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.getOne(lambdaQueryWrapper);
                flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
                flowTaskOperatorRecordEntity.setSignImg(flowModel.getSignImg());
                flowTaskOperatorRecordEntity.setFileList(JsonUtil.getObjectToString(flowModel.getFileList()));
                flowTaskOperatorRecordService.updateById(flowTaskOperatorRecordEntity);
                taskService.complete(task.getId());
            }
        }

    }





    @Override
    public ActionResult shareEx(String id) {
        HistoricProcessInstance historicProcessInstance = activitiUtils.getHistoricProcessInstanceByIdOrBusinessKeyOrTaskId(id);
        activitiUtils.validProcessStatus(historicProcessInstance.getId());
        UserInfo userInfo = userProvider.get();
        LambdaQueryWrapper<FlowTaskShareEntity> lambdaQueryWrapper= new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FlowTaskShareEntity::getTaskId,historicProcessInstance.getId());
        lambdaQueryWrapper.eq(FlowTaskShareEntity::getObjectId,userInfo.getUserId());
        lambdaQueryWrapper.eq(FlowTaskShareEntity::getObjectType,"1");
        FlowTaskShareEntity one = flowTaskShareService.getOne(lambdaQueryWrapper);
        if(one==null){
            Process bpmnModelMainProcess = getBpmnModelMainProcess(historicProcessInstance.getProcessDefinitionId());
            UserTask firstNode = getFirstNode(bpmnModelMainProcess);
            FlowTaskShareEntity flowTaskShareEntity = new FlowTaskShareEntity();
            flowTaskShareEntity.setId(RandomUtil.uuId());
            flowTaskShareEntity.setObjectType("1");
            flowTaskShareEntity.setObjectId(userInfo.getUserId());
            flowTaskShareEntity.setNodeCode(firstNode.getId());
            flowTaskShareEntity.setNodeName(firstNode.getName());
            List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(historicProcessInstance.getId()).taskDefinitionKey(firstNode.getId()).listPage(0, 1);
            flowTaskShareEntity.setTaskNodeId(historicTaskInstances.get(0).getId());
            flowTaskShareEntity.setTaskId(historicProcessInstance.getId());
            Map<String, Object> map = historicProcessInstance.getProcessVariables();
            String applyUserID = MapUtil.getStr(map, APPLY_USER_ID);
            UserEntity userEntity = userService.getInfo(applyUserID);
            flowTaskShareEntity.setEnCode(MapUtil.getStr(map,BILL_CODE));
            flowTaskShareEntity.setFullName(MapUtil.getStr(map,BUSINESS_TITLE));
            flowTaskShareEntity.setTemplateId(MapUtil.getStr(map,FLOW_ENGINE_ID));
            flowTaskShareEntity.setFlowId(MapUtil.getStr(map,FLOW_TEMPLATE_JSON_ID));
            flowTaskShareEntity.setFlowCategory(MapUtil.getStr(map,PROCESS_CATEGORY));
            flowTaskShareEntity.setFlowUrgent(MapUtil.getInt(map,FLOW_URGENT));
            flowTaskShareEntity.setCreatorTime(new Date());
            flowTaskShareEntity.setApplyUserId(userEntity.getRealName()+"/"+userEntity.getAccount());
            flowTaskShareEntity.setApplyUserIdReal(userEntity.getId());
            flowTaskShareEntity.setProcessStatus(MapUtil.getInt(map,PROCESS_STATUS));
            flowTaskShareService.save(flowTaskShareEntity);
            return ActionResult.success("关注成功");
        }
        else{
            //
            flowTaskShareService.removeById(one.getId());
            return ActionResult.success("取关成功");
        }




    }






    private Map<String, ChildNode> iteratorChildNode(Map<String, ChildNode> childNodeMap,ChildNode childNode) {
        ChildNode subChildNode = childNode.getChildNode();
        if(subChildNode!=null){
            childNodeMap.put(subChildNode.getNodeId(),subChildNode);
            iteratorChildNode(childNodeMap,subChildNode);
            List<ChildNode> conditionNodes = subChildNode.getConditionNodes();
            if(CollUtil.isNotEmpty(conditionNodes)){
                for (ChildNode conditionNode : conditionNodes) {
                    childNodeMap.put(conditionNode.getNodeId(),conditionNode);
                    iteratorChildNode(childNodeMap,conditionNode);
                }
            }

        }
        else{
            List<ChildNode> conditionNodes = childNode.getConditionNodes();
            if(CollUtil.isNotEmpty(conditionNodes)){
                for (ChildNode conditionNode : conditionNodes) {
                    childNodeMap.put(conditionNode.getNodeId(),conditionNode);
                    iteratorChildNode(childNodeMap,conditionNode);
                }
            }
        }
        return childNodeMap;
    }


    private void insTimeOutRedis(FlowModel flowModel, Collection<FlowTaskOperatorEntity> operatorList, UserInfo userInfo, FlowTaskEntity flowTask, List<FlowTaskNodeEntity> nodeList) {
        for (FlowTaskOperatorEntity operatorOne : operatorList) {
            FlowTaskNodeEntity taskNodeEntity = nodeList.stream().filter(t -> t.getId().equals(operatorOne.getTaskNodeId())).findFirst().orElse(null);
            boolean flag = ifInsRedis(taskNodeEntity, nodeList);
            if (flag) {
                WorkTimeoutJobModel workTimeoutJobModel = WorkTimeoutJobModel.builder().flowModel(flowModel)
                        .taskId(flowTask.getId()).taskNodeId(operatorOne.getTaskNodeId()).taskNodeOperatorId(operatorOne.getId()).operatorEntity(operatorOne)
                        .tenantId(userInfo.getTenantId()).build();
                workTimeoutJobUtil.insertRedis(workTimeoutJobModel, redisUtil);
            }
        }
    }

    /**
     * 封装超时消息
     *
     * @return
     */
    public boolean ifInsRedis(FlowTaskNodeEntity taskNodeEntity, List<FlowTaskNodeEntity> nodeList) {
        ChildNodeList childNode = JsonUtil.getJsonToBean(taskNodeEntity.getNodePropertyJson(), ChildNodeList.class);
        LimitModel timeLimitConfig = childNode.getProperties().getTimeLimitConfig();
        FlowTaskNodeEntity startNode = nodeList.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).findFirst().orElse(null);
        if (timeLimitConfig.getOn() == 0) {
            return false;
        } else if (timeLimitConfig.getOn() == 2) {
            ChildNodeList childNodeStart = JsonUtil.getJsonToBean(startNode.getNodePropertyJson(), ChildNodeList.class);
            if (childNodeStart.getProperties().getTimeLimitConfig().getOn() == 0) {
                return false;
            }
        }
        return true;
    }
}
